zoukankan      html  css  js  c++  java
  • [LeetCode] 268. Missing Number ☆(丢失的数字)

    转载:http://www.cnblogs.com/grandyang/p/4756677.html

    描述

    Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

    For example,
    Given nums = [0, 1, 3] return 2.

    Note:
    Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

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

    说明:

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

    解析、代码

    求和法

    这道题给我们n个数字,是0到n之间的数但是有一个数字去掉了,让我们寻找这个数字,要求线性的时间复杂度和常数级的空间复杂度。那么最直观的一个方法是用等差数列的求和公式求出0到n之间所有的数字之和,然后再遍历数组算出给定数字的累积和,然后做减法,差值就是丢失的那个数字,参见代码如下:

    解法一:

    复制代码
    class Solution {
    public:
        int missingNumber(vector<int>& nums) {
            int sum = 0, n = nums.size();
            for (auto &a : nums) {
                sum += a;
            }
            return 0.5 * n * (n + 1) - sum;
        }
    };
    复制代码

     异或法

    这题还有一种解法,使用位操作Bit Manipulation来解的,用到了异或操作的特性,相似的题目有Single Number 单独的数字, Single Number II 单独的数字之二Single Number III 单独的数字之三。那么思路是既然0到n之间少了一个数,我们将这个少了一个数的数组合0到n之间完整的数组异或一下,那么相同的数字都变为0了,剩下的就是少了的那个数字了,参加代码如下:

     nums[index] = index

    解法二:

    复制代码
    class Solution {
    public:
        int missingNumber(vector<int>& nums) {
            int res = 0;
            for (int i = 0; i < nums.size(); ++i) {
                res ^= (i + 1) ^ nums[i];
            }
            return res;
        }
    };
    复制代码
    public int missingNumber(int[] nums) {
            int res = nums.length;
            for (int i = 0; i < nums.length; ++i) {
                res ^= (i) ^ nums[i];
            }
            return res;
        }

     二分法

    这道题还可以用二分查找法来做,我们首先要对数组排序,然后我们用二分查找法算出中间元素的下标,然后用元素值和下标值之间做对比,如果元素值大于下标值,则说明缺失的数字在左边,此时将right赋为mid,反之则将left赋为mid+1。那么看到这里,作为读者的你可能会提出,排序的时间复杂度都不止O(n),何必要多此一举用二分查找,还不如用上面两种方法呢。对,你说的没错,但是在面试的时候,有可能人家给你的数组就是排好序的,那么此时用二分查找法肯定要优于上面两种方法,所以这种方法最好也要掌握以下~

    解法三:

    复制代码
    class Solution {
    public:
        int missingNumber(vector<int>& nums) {
            sort(nums.begin(), nums.end());
            int left = 0, right = nums.size();
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] > mid) right = mid;
                else left = mid + 1;
            }
            return right;
        }
    };
    复制代码

    在CareerCup中有一道类似的题,5.7 Find Missing Integer 查找丢失的数,但是那道题不让我们直接访问整个int数字,而是只能访问其二进制表示数中的某一位,强行让我们使用位操作Bit Manipulation来解题,也是蛮有意思的一道题。

  • 相关阅读:
    CF #536div2E(dp)
    BZOJ2440(容斥+莫比乌斯函数)
    莫比乌斯反演题目结(下)
    struts 文件上传示例
    struts 文件上传示例
    struts2请求过程源码分析
    struts2请求过程源码分析
    如何快速成为数据分析师?
    如何快速成为数据分析师?
    多对多 hibernate映射
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/10221697.html
Copyright © 2011-2022 走看看