异或总结

异或性质:相同为0,不同为1(无进位相加)

1.由于0^0=0 0^1=1 所以,0^任何数 = 任何数。

2.由于1^0=1 1^1 =0所以,1^任何数 = 任何数取反。

3.任何数^任何数 = 0。

4.用于将特定的位反转,如对10100001的第2位和第3位翻转,可以将数与00000110进行按位异或运算。

5.通过按位异或运算,可以实现两个值的交换,而不必使用临时变量。

6.异或运算的特点:a两次异或同一个数b(a=a ^ b ^ b)仍然为原值a。

7.异或是可交换的:a^b = b^a。

例1:不使用临时变量交换a和b的值。
a= 10100001
b= 00000111
a=a^b; //a=10100110
//此步操作是将a b原值的相同位记录为0,不同位记录为1.
//并保存在a中,b值此步并没有发生变化
//由于1^任何数 = 任何数取反 0^任何数 = 任何数
b=b^a; //b=10100001
//a中用1表示原值中对应位不同的部分
//做异或操作是将b中与(原a)中相同的部分保留,与(原a)中不同的部分取反
//即将b编程原来的a
a=a^b //a=00000111
//由于此时的a表示异同,b表示原来的a
//同理第二部步可获得原b值,赋给a即可实现转换

LeetCode——面试题 16.01. 交换数字

题目描述:
编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。

提示:
numbers.length == 2

示例:
输入: numbers = [1,2]
输出: [2,1]

代码如下:

class Solution {
    
    
public:
    vector<int> swapNumbers(vector<int>& numbers) {
    
    
        numbers[0]=numbers[0]^numbers[1];
        numbers[1]=numbers[0]^numbers[1];
        numbers[0]=numbers[1]^numbers[0];
        return numbers;
    }
};

执行结果:
在这里插入图片描述

例2:
任何一个数字异或它自己都等于0。也就是说,如果我们从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些出现两次的数字全部在异或中抵消掉了。

#include<iostream>
#include<vector>
using namespace std;
int main(){
    
    
	int res = 0;
	vector<int> v{
    
     1,2,2,3,1,8,8 };
	for (int i = 0; i < v.size() ; i++){
    
    
		res ^= v[i];
		cout << res << " ";
	}
	return 0;
}

例3:LeetCode——面试题 17.04. 消失的数字

题目描述:
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
示例 1:
输入:[3,0,1]
输出:2
示例 2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8
代码如下:
方法1:(使用异或,利用了特点6)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int ans=0;
        for(int i=0;i<size;i++){
    
    
            ans^=i;
            ans^=nums[i];
        }
        ans^=size;
        return ans;
    }
};

方法二:(从0到n求和减去nums数组求和,即为缺失的数)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int sum1=0,sum2=0;
        for(int i=0;i<size;i++){
    
    
            sum1+=nums[i];
            sum2+=i;
        }
        return sum2+size-sum1;
    }
};

方法三:(直接找到那个缺失的数,但是时间复杂度超过了O(n),仅供参考)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int ans=-1;
        sort(nums.begin(),nums.end());
        for(int i=0;i<size;i++){
    
    
            if(nums[i]!=i){
    
    
                ans=i;
                break;
            }
        }
        if(ans==-1){
    
    
            return size;
        }
        return ans;
    }
};

执行结果:
在这里插入图片描述
例四:LeetCode——389. 找不同

题目描述:
给定两个字符串 s 和 t,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。

示例 1:
输入:s = “abcd”, t = “abcde”
输出:“e”
解释:‘e’ 是那个被添加的字母。

示例 2:
输入:s = “”, t = “y”
输出:“y”

示例 3:
输入:s = “a”, t = “aa”
输出:“a”

示例 4:
输入:s = “ae”, t = “aea”
输出:“a”

代码如下:

class Solution {
    
    
public:
    char findTheDifference(string s, string t) {
    
    
        char ch=0;
        for(int i=0;i<s.size();i++){
    
    
            ch^=s[i];
        }
        for(int j=0;j<t.size();j++){
    
    
            ch^=t[j];
        }
        return ch;
    }
};

执行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/FYPPPP/article/details/110948903