知识点讲解:
一、异或操作定义:
异或是指相同为0,不同为1,也可理解为无进位相加!! 很重要!!
二、关于异或运算的几个性质:
1.0^N=N (0和任何数异或都是原来的数)
2.N^N=0 (任何数异或自己都是0)
3.满足交换律和结合律:
所以无论怎么改变顺序,最后的结果都是一样的!!
4.重要!!!!
刷题:
一、第一题:只出现一次的数字1
1.题目描述:
2.分析题目:
这个题目还比较简单哈,直接应用我上边的异或的一些性质,以及联系题目的描述,就知道用异或是最方便的,偶数次出现的数都会被消掉,最后留下来的肯定就是基数次出现的那个数辣,所以用for循环就可以求解了,一遍过哈
3.题解:
class Solution {public int singleNumber(int[] nums) {int sum=nums[0];for(int i=1;i<nums.length;i++){sum=sum^nums[i];}return sum;}
}
二、第二题:丢失的数字
1.题目描述:
2.分析题目:
这个题目可以参考我的上边的异或运算的第三个性质,整体异或和 异或上 整体中部分的异或和 等于整体-部分的那部分数字的异或和,我刚开始写这个题目没有想到这个知识点,以为把这部分的结果异或出来就是缺失的那部分值了,但是显然不是,测试点只过了一个,所以代码如下:
3.题解:
由于0异或任何数都等于原来的那个数,所以这里可以放心的初始化数据为0
class Solution {public int missingNumber(int[] nums) {int ErAll=0;int Erpart=0;//由于0异或任何数都等于原来的那个数,所以这里可以放心的初始化数据为0for(int i=0;i<nums.length;i++){ErAll^=i;Erpart^=nums[i];}ErAll^=nums.length;return ErAll^Erpart;}
}
三、第三题:只出现一次的数字3
1.题目描述:
2.分析题目:
这个题目和第一个题目一样,难道是要卡时间复杂度么,这里好像是nums[i]范围有了一定的变化,我天,惹,好像是这里是两个元素只出现了一次,所以困难就是如何通过这个最后异或结果得到的a^b来把最后的a和b分别计算出来,例如题目中的nums1这个数组:
那么3和5异或的结果就是0110,结果最右边的1就代表他们这个位置上的0还是1是不一样的,那么我们就可以知道这个数组中一定可以分为这个位置是0还是1的两部分数字
那么:
第一类 这个第i个位置上是0 A组
第二类 这个第i个位置上是1 B组
因为无论偶数次出现的数字这个位置是什么,他们一定要么分到A组,要么分到B组,而且还都是偶数次出现的,所以这样把他们分类之后,A组和B组就又像第一题里边一样,只有一个只出现一次的数字了,所以把这个组里边的数字异或出来就是要求得的其中一个结果
最后这个结果和最开始把所有数字都异或的结果相异或,就得到了另一个数字结果
这样就求出来了
补充:如何找到int类型的数字最靠右的1
3.题解:
惹,错误答案,只过了6个测试点:
class Solution {public int[] singleNumber(int[] nums) {int result=0;int result1=0;for(int i=0;i<nums.length;i++){result^=nums[i];}//找到最右边的第一个1int right=result&(-result);for(int i=0;i<nums.length;i++){if((right ^ nums[i])!=nums[i])result1^=nums[i];}int b=0;b=result1^result;return new int[]{result1,b};}
}
惹,好家伙,只需要把判断阵营那里的代码修改一下就可以了,改成下面的:
if((right & nums[i])!=0)result1^=nums[i];
但是为啥异或不等于它本身不能用来判断阵营啊??
0110----->0010
0010
0001
我知道了,笑死我了,这样怎么可能等于本身,直接等于0了,笑死,因为你看,上边---->符号右边的就是得出来的那个最右边为1的那个数,我想的是如果其他数不为0,那么异或出来肯定还是本身啊,那么就只需要管判断阵营的那个数字是啥了,那么就分两种情况
???不对啊,就是不是它本身,不是它本身就说明不是它的阵营,哦对,不同阵营就会被判成1,还是不是和原来一样,所以确实搞错了
========分割线,上边在胡言乱语哈,纯属心理博弈:
其实我的做法问啥错呢,因为我把异或结果是否是本身作为了这个衡量标准,但是你想,除了要判断的那位数,其他位置上的数确实因为与0相异或而没变,但是如果要判断的那个位置上是0,与1异或,结果就是1,如果位置上是1,那么结果就是0,总而言之,无论是哪一种阵营里边的数,其实异或之后都绝对不是它本身,所以这个解法是错的,
所以还是&之后结果是0还是不是0,更能作为判断依据
ok,今天就写到这,下班,