题目(难度中等)
下标从 0 开始、长度为 n 的数组 derived 是由同样长度为 n 的原始 二进制数组 original 通过计算相邻值的 按位异或(⊕)派生而来。
特别地,对于范围 [0, n - 1] 内的每个下标 i :
如果 i = n - 1 ,那么 derived[i] = original[i] ⊕ original[0]
否则 derived[i] = original[i] ⊕original[i + 1]
给你一个数组 derived ,请判断是否存在一个能够派生得到 derived 的 有效原始二进制数组 original 。
如果存在满足要求的原始二进制数组,返回 true ;否则,返回 false 。
二进制数组是仅由 0 和 1 组成的数组。
示例 1
输入:derived = [1,1,0]
输出:true
解释:能够派生得到 [1,1,0] 的有效原始二进制数组是 [0,1,0] :
derived[0] = original[0] ⊕ original[1] = 0 ⊕ 1 = 1
derived[1] = original[1] ⊕ original[2] = 1 ⊕ 0 = 1
derived[2] = original[2] ⊕ original[0] = 0 ⊕ 0 = 0
示例 2
输入:derived = [1,1]
输出:true
解释:能够派生得到 [1,1] 的有效原始二进制数组是 [0,1] :
derived[0] = original[0] ⊕ original[1] = 1
derived[1] = original[1] ⊕ original[0] = 1
示例 3
输入:derived = [1,0]
输出:false
解释:不存在能够派生得到 [1,0] 的有效原始二进制数组。
提示
n == derived.length
1 <= n <= 10^5
derived 中的值不是 0 就是 1 。
题解——模拟
其实这里的难点在于知道这个异或交换律,即将derived数组再异或一边
在本题中derived[i]就是c,a就是original[i],b是original[i+1]
所以derived[i] = original[i] ^ original[i+1]
所以给出一个original[i]时,就可以根据derived[i]推出
original[i+1] = derived[i]^original[i]
所以利用这个规律在给定一个初始的original[0]之后,根据derived[i]一步一步可推出original[i],但是这个original[i]是否正确,还需要判断推导出来的最后一个数字是否等于original[0],因为这是一个回环。
这题的完整思路就是模拟:
(1)模拟,枚举起始为0和1两种情况。
(2)求原始数组,判断首尾是否相等。
代码
class Solution {
public:
bool exclusiveOr(int start, vector<int>& derived)
{
int curVal = start;
cout << curVal << " ";
for(int i = 0; i < derived.size(); i++)
{
curVal ^= derived[i];
// cout << curVal << " ";
}
return start == curVal;
}
bool doesValidArrayExist(vector<int>& derived) {
return exclusiveOr(0,derived) && exclusiveOr(1,derived);
}
};
题目链接
https://leetcode.cn/problems/neighboring-bitwise-xor/
参考链接
【1】https://leetcode.cn/problems/neighboring-bitwise-xor/solution/2683-xiang-lin-zhi-de-an-wei-yi-huo-ti-j-j0vn/
【2】https://zhuanlan.zhihu.com/p/363504637