这道算法题太太太太太简单啦

 
 

640?wx_fmt=jpeg

今天分享一道很简单的算法题。

题目来源于 LeetCode 上第 268 号问题:缺失数字。题目难度为 Easy,目前通过率为 50.2% 。

题目描述

给定一个包含 0, 1, 2, ..., nn 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

640?wx_fmt=png

题目解析

这道题目有三种解法。

解法一:异或法

和之前那道 只出现一次的数字 很类似:

只出现一次的数字:  给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

如果我们补充一个完整的数组和原数组进行组合,那所求解的问题就变成了 只出现一次的数字

将少了一个数的数组与 0 到 n 之间完整的那个数组进行异或处理,因为相同的数字异或会变为了 0 ,那么全部数字异或后,剩下的就是少了的那个数字。

640?wx_fmt=png
代码实现1
class Solution {    public int missingNumber(int[] nums) {        int res = 0, i = 0 ;        //注意数组越界情况        for ( i = 0; i < nums.length;i++){            // i 表示完整数组中的数字,与原数组中的数字 nums[i] 进行异或,再与保存的结果异或            res = res^i^nums[i];        }        //最后需要与循环中无法使用到的那个最大的数异或        return res^i;    }}
    public int missingNumber(int[] nums) {
        int res = 0, i = 0 ;
        //注意数组越界情况
        for ( i = 0; i < nums.length;i++){
            // i 表示完整数组中的数字,与原数组中的数字 nums[i] 进行异或,再与保存的结果异或
            res = res^i^nums[i];
        }
        //最后需要与循环中无法使用到的那个最大的数异或
        return res^i;
    }
}
代码实现2
class Solution {   public int missingNumber(int[] nums) {    int res = nums.length;    for (int i = 0; i < nums.length; ++i){        res ^= nums[i];        res ^= i;    }    return res;  }}
   public int missingNumber(int[] nums) {
    int res = nums.length;
    for (int i = 0; i < nums.length; ++i){
        res ^= nums[i];
        res ^= i;
    }
    return res;
  }
}

解法二:求和法

640?wx_fmt=gif

//小吴之前担心会数据溢出,不过估计这题考察的不是这个,所以测试用例没写这种吧,还是能 AC 的class Solution {   public int missingNumber(int[] nums) {        int n = nums.length;        int sum = (n+0)*(n+1)/2;        for (int i=0; i<n; i++){            sum -= nums[i];        }        return sum; }}
class Solution {
   public int missingNumber(int[] nums) {
        int n = nums.length;
        int sum = (n+0)*(n+1)/2;
        for (int i=0; i<n; i++){
            sum -= nums[i];
        }
        return sum;
 }
}

解法三:二分法

将数组进行排序后,利用二分查找的方法来找到缺少的数字,注意搜索的范围为 0 到 n 。

注:由于一开始进行了排序操作,因此使用二分法的性能是不如上面两种方法。

public class Solution {    public int missingNumber(int[] nums) {        Arrays.sort(nums);        int left = 0;        int right = nums.length;        while (left < right){            int mid = (left + right) / 2;            if (nums[mid] > mid){                right = mid;            }else{                left = mid + 1;              }        }        return left;    }}class Solution {
    public int missingNumber(int[] nums) {
        Arrays.sort(nums);
        int left = 0;
        int right = nums.length;
        while (left < right){
            int mid = (left + right) / 2;
            if (nums[mid] > mid){
                right = mid;
            }else{
                left = mid + 1;  
            }
        }
        return left;
    }
}

END

640?wx_fmt=png



推荐阅读







640?wx_fmt=png



欢迎长按下图关注公众号五分钟学算法,一起学习交流。

640?wx_fmt=jpeg

来和程序员小吴一起学算法

640?wx_fmt=gif


我就知道你在看!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值