博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础算法面试题---异或运算II
阅读量:2492 次
发布时间:2019-05-11

本文共 2419 字,大约阅读时间需要 8 分钟。

前言

最近在leetcode发现两道异或相关的题目,觉得挺好的,拿出来分享一下。

异或满足的规律

公式还是要清楚的

1、归零率:a ^ a = 0(自己异或自己结果为0)
2、恒等率:a ^ 0 = a(与0异或结果不变)
3、交换律:a ^ b = b ^ a
4、结合律:a ^ b ^ c = a ^ (b ^ c )

第一题:解码异或后的数组(leetcode.1720)

在这里插入图片描述

难度:简单

题目中给出的encoded[i] 公式如下:

encoded[i] = arr[i] XOR arr[i + 1]

我们可以利用归零律、恒等率、结合律,让等号两边同时异或arr[i + 1],即得到:

encoded[i] XOR arr[i + 1] = arr[i] XOR arr[i + 1] XOR arr[i + 1],

又因为:arr[i + 1] XOR arr[i + 1] 等于 0,arr[i] XOR 0 等于 arr[i]

所以最终公式变为:

arr[i] = encoded[i] XOR arr[i + 1]

题目中恰好又告诉了我们arr[0]的值,所以最终我们便能计算出arr数组中每个位置的值。

解题代码

public class LC_1720 {
public int[] decode(int[] encoded, int first) {
int n = encoded.length + 1; int[] ans = new int[n]; ans[0] = first; for (int i = 1; i < n; i++) {
ans[i] = encoded[i - 1] ^ ans[i - 1]; } return ans; }}

第二题:解码异或后的排列(leetcode.1734)

在这里插入图片描述

难度:中等

很显然本题从 encoded[i] = perm[i] XOR perm[i + 1] 这个公式开始分析,与第一题给出的公式一样,区别在与不知道perm数组第一个下标的元素值是多少了,那我们猜想假设我们能得到第一个下标的值,那么这题就解决了。

我们再分析题目,给出的条件中,指出perm 是前 n 个正整数的排列,且 n 是个 奇数 。

假设n等于5,那么perm中的数字就是由,1-5组成,假设就是【1,2,3,4,5】,顺序不一定,但是值一定是这5个数字的排列组合。

再回到encoded[i] = perm[i] XOR perm[i + 1] 公式中,我们可以看出:

encoded[0] = perm[0] XOR perm[1]

encoded[1] = perm[1] XOR perm[2]

那么encoded数组中所有数的异或结果应该如下:

perm[0] XOR perm[1] XOR perm[1] XOR perm[2] XOR perm[2] XOR perm[3]。。。XOR perm[n-1] XOR perm[n]

如果这样一直下去最终encoded数组中所有数异或的结果实际上就等于

perm[0] XOR perm[n]

这看起来没什么用,那我们换一个方式,不妨我们每隔一位异或一下,也就是:

encoded[0] XOR encoded[2] XOR encoded[4]。。。

那么最终将会得到:

perm[0] XOR perm[1] XOR perm[2] XOR perm[3] XOR perm[4] XOR perm[5]

也就得到了perm数组每一位异或后的结果。

现在我们再回到,perm 是前 n 个正整数的排列,这个条件中,上面已经说过了,perm下标1-5实际上就是数字1-5,只不过不一定数字和下标不一定是按照顺序对应而已,但是这并对于结合律来说并没有影响,所以我们只要让1-5异或即可。

上半部分:perm[0] XOR perm[1] XOR perm[2] XOR perm[3] XOR perm[4] XOR perm[5]

XOR

下半部分:1 XOR 2 XOR 3 XOR 4 XOR 5

又因为 perm[1] XOR perm[2] XOR perm[3] XOR perm[4] XOR perm[5],就是对应这1到5的异或结果,所以最终上下异或后得到perm[0]。

好了,现在我们终于拿到了perm[0],接下来按照第一题的方法即可。

代码

class Solution {
public int[] decode(int[] encoded) {
int[] ans = new int[encoded.length + 1]; int n = encoded.length + 1; int a = 0; for (int i = 1; i <= n; i++) {
a ^= i; } int e = 0; for (int i = 1; i < encoded.length; i += 2) {
e ^= encoded[i]; } ans[0] = a ^ e; for (int i = 0; i < encoded.length; i++) {
ans[i + 1] = ans[i] ^ encoded[i]; } return ans; }}

转载地址:http://welrb.baihongyu.com/

你可能感兴趣的文章
hive常用函数及数据结构介绍
查看>>
Hive面试题干货(亲自跟着做了好几遍,会了的话对面试大有好处)
查看>>
力扣题解-230. 二叉搜索树中第K小的元素(递归方法,中序遍历解决)
查看>>
力扣题解-123. 买卖股票的最佳时机 III(动态规划)
查看>>
Django 源码阅读:服务启动(wsgi)
查看>>
Django 源码阅读:url解析
查看>>
Docker面试题(一)
查看>>
第一轮面试题
查看>>
2020-11-18
查看>>
Docker面试题(二)
查看>>
一、redis面试题及答案
查看>>
消息队列2
查看>>
C++ 线程同步之临界区CRITICAL_SECTION
查看>>
测试—自定义消息处理
查看>>
MFC中关于虚函数的一些问题
查看>>
根据图层名获取图层和图层序号
查看>>
规范性附录 属性值代码
查看>>
提取面狭长角
查看>>
Arcsde表空间自动增长
查看>>
Arcsde报ora-29861: 域索引标记为loading/failed/unusable错误
查看>>