LeetCode-268. Missing Number

Description:

这里写图片描述

Example 1:

这里写图片描述

Example 2:

这里写图片描述

Note:

这里写图片描述

Solution1 (C++):

这里写图片描述

Solution2 (C++):

这里写图片描述

Solution3 (C++):

这里写图片描述

算法分析:

解法一:这一道题的解法我参考了之前的一道题的方法。LeetCode-448. Find All Numbers Disappeared in an Array
因为之所以想到这个方法是因为首先都是要找到数组里消失的元素,然后要找到数组里的元素的变化范围都在0~n之内。所以我尝试在数组内部通过变换找到消失的元素。其实解法不难。但我还是有两个地方卡了一下:

  1. 由于数组元素最大可到达n,而数组索引最大值为n-1,所以必须事先判断将数组元素的值作为索引重新传入数组的时候,判读元素的值会不会超过索引最大值。
  2. 由于我是通过将数组的元素取反的方法来判断,对应的元素的索引有没有访问过。而最头疼的一个地方就是0,可以分为两种情况,当0所在的位置有元素对应,那么,假如i=6,nums[6]=0,这时应该让i=6对应的元素值取负数,表示6这个元素存在,然而这时i=6对应的是0,0取负数还是0,而当0所在的位置正好缺少那个元素对应的数,比如说数列:[1,2,0],那么这个时候,0应该不会取反,如果换成其他数,就会是正数,然后被后面的一遍遍历查找出来,然而这是0.所以0就很头疼。

为了解决这个问题,我才有了第一遍遍历都将数列中的元素+1.


解法二:这个就是借用了数学思维了。很简单,将应该完整的数列全部加起来,然后减去实际的数列中所有元素的和,就能得到缺少的元素了。很简单,但是解法二能对解法三的理解起到一定的帮助。


解法三:这个方法更加普遍。关键在于异或的使用。其实这个思路也很简单,充分利用了异或运算符的特点。那就是a^b^b=a。为什么?因为b^b=0,而a^0=a。所以,这个题目我们可以首先把0~n全部异或一遍。然后将结果与数列中的元素全部异或以便。对于数列中应有的元素,会异或两次,而消失的那个元素,只会异或一次。那么这样全部运算的结果就自然是消失的元素了。可以证明如下:

//设a0,a1,a2,a3,...,an就是0,1,2,3,...,n;
//数列缺少元素ai;
//第一次异或结果为:
int res1=a0^a1^a2^a3^...^ai^...^an;
//然后与数列中元素进行异或:
int res2=res1^a0^a1^a2^...^ai-1^ai+1^...^an
        =a0^a1^a2^a3^...^ai-1^ai^ai+1...^an^
         a0^a1^a2^a3^...^ai-1^  ^ai+1...^an
        =0 ^0 ^0 ^0 ^...^0   ^ai^0   ...^0
        =ai.
//证明完毕。 

程序分析:

程序中要注意的地方就是这里使用了新的for遍历vector的方法:

for(int num:nums){
    //......num每次循环会自动赋为i=0,1,2,...,n-1对于的元素值
}

然后就是异或运算符^,常用运算公式有:

  • 0^0=0,1^1=0;
  • 0^1=1,1^0=1;
  • a^0=a,a^1=~a;
  • a^a=0,a^~a=1;
  • a^b=b^a;
  • a^b^c=a^c^b;
  • a^b^b=a^0=a;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值