剑指offer--缺失的数字

Posted 雨轩(小宇)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer--缺失的数字相关的知识,希望对你有一定的参考价值。

1、消失的数字
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
示例:

输入:[9,6,4,2,3,5,7,0,1]
输出:8

思路一:
异或,设置一个变量num,先将索引 0 - numsSize 与 num 异或,在将nums[ i ] 与 num 异或,最后在循环外,在将 num 与 numsSize 进行异或,num就是缺失的数字。

int missingNumber(int* nums, int numsSize){
    //方法一:异或
    int i = 0;
    int num = 0;
    for(i=0;i<numsSize;i++)
    {
        num ^= i;
        num ^= nums[i];
    }
    num ^= numsSize;
    return num;
}

思路二:
等差数列求和,求出 0 - numsSize 的总和,在减数组的总和,既为缺失的数字。

int missingNumber(int* nums, int numsSize){
	int i=0;
    int num=0;
    for(i=0;i<numsSize;i++)
    {
        num+=nums[i];
    }
    num=(numsSize*(numsSize+1))/2-num;
    return num;
}

2、消失的两个数字
给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?
示例 1:

输入: [2,3]
输出: [1,4]

思路一:
先将变量num 与 索引异或,由于缺失两个数字,所以与的时候,是与 1 - numsSize+2,这里得到1-N的与结果,num 在&数组中的值,num就是缺失的两个数字的异或。
接下来,用一个数 x 来表示 num & -num,求下次&偶数,还是&奇数,再用一个变量first用来装偶数或者奇数的异或结果,在将first 与 数组中的值,first就是其中一个缺失的数,first & num 就是第二个缺失的数。

int* missingTwo(int* nums, int numsSize, int* returnSize){
    int num = 0;
    int i = 0;
    static int ans[2];//用来装缺失的数
    memset(ans,0,8);//设置数组值为0
    for(i = 1; i <= numsSize +2 ; i++) //将索引全部异或
        num ^= i;
    for(i = 0; i < numsSize; i++)//将数组值异或
        num ^= nums[i];
    int first = 0;
    int x = num & -num;//求出下面的与,是与偶数,还是奇数
    for(i = 1; i <= numsSize +2 ; i++)
    {
        if(x & i)
            first ^= i;//异或,x=1,只有1和3可以进入,得到这两个的异或值,first=010;
    }
    for(i = 0; i < numsSize; i++)
    {
        if(x & nums[i])
            first ^= nums[i];//异或求出其中一个缺失的数,011&010=001,求出第一个缺失的数为1
    }
    ans[1] = first;
    ans[0] = first ^ num;
    *returnSize=2;
    return ans;
}

思路二:
求和,先求出索引1-N的总和,在求出数组值的总和,利用总的数减去已有的数,剩下的是缺失的两个数字的总和。
在利用缺失的两个数字的大小关系,求出limits,在利用nums[ i ] <= limits求出其中小于limits的总和,在利用关系式子 limits * (limits + 1) / 2 减去小于limits的总和,即为其中缺失的一个数字,在利用两数之和求出另外一个缺失的数

int* missingTwo(int* nums, int numsSize, int* returnSize){
    //方法一:求和,先求出1-N的和,在利用缺失的数字的大小关系求出
    int sum = 0;
    int n = numsSize + 2;
    n = n*(n + 1)/2;
    for(int i = 0;i < numsSize; i++)
        sum += nums[i];
    int sumTwo = n - sum;//缺失的两个数字总和
    int limits = sumTwo / 2;//因为缺失的两个数字有大小关系,limits用来限制
    sum = 0;
    for(int i = 0;i < numsSize; i++)
    {
        if(nums[i] <= limits)
            sum += nums[i];//求出其中小于limits的数字总和
    }
    int one = limits * (limits + 1) / 2 - sum;//求出其中一个缺失的数字
    int two = sumTwo - one;
    static int arr[2];
    memset(arr,0,8);
    arr[1] = one;
    arr[0] = two;
    *returnSize = 2;
    return arr;

制作不易,点个赞!!!

以上是关于剑指offer--缺失的数字的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer--缺失的数字

剑指offer python版 0到n-1中缺失的数字

剑指Offer面试题53 - II. 0~n-1中缺失的数字

剑指 Offer 53 - II. 0~n-1中缺失的数字

剑指OFFER----面试题53 - II. 0~n-1中缺失的数字

LeetCode(剑指 Offer)- 53 - II. 0~n-1中缺失的数字