缺失数字,给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

题记:

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

示例 1:

输入 :nums = [3,0,1]
输出 :2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2是丢失的数字,因为它没有出现在 nums 中。

示例 2:

输入 :nums = [0,1]
输出 :2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2是丢失的数字,因为它没有出现在 nums 中。

示例 3:

输入 :nums = [9,6,4,2,3,5,7,0,1]
输出 :8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围[0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。

示例 4:

输入 :nums = [0]
输出 :1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1是丢失的数字,因为它没有出现在 nums 中。

提示:

  • n == nums.length
  • 1 <= n <= 10 ^ 4
  • 0 <= nums[i] <= n
  • nums 中的所有数字都 独一无二

**进阶:**你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?

题目来源:

作者:LeetCode

链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xnj4mt/

来源:力扣(LeetCode)

解题方法

自己想的:

补全数组,再比较差集即可

代码为:

php 复制代码
/**
 * @param Integer[] $nums
 * @return Integer
 */
function missingNumber($nums) {
    $length = count($nums);
    $nums_array = [];
    //补全数组,再比较差集即可
    for($i = 0; $i <= $length; $i++){
        array_push($nums_array, $i);
    }
    $res = array_diff($nums_array, $nums);
    return current($res);
}

其他方法:

官方PHP代码:

php 复制代码
/**
 * @param Integer[] $nums
 * @return Integer
 */
function missingNumber($nums) {
    //从0开始填充n(nums的长度+1)个1,[3,0,1]为例
    $result = array_fill(0, count($nums)+1, 1); //[1,1,1,1]
    foreach($nums as $num) {
        $result[$num]--;    //[0,0,1,0]
    }

    //result的那个值大于0,对应的键值就位确实的数字
    foreach($result as $k => $v) {
        if($v > 0) {
            return $k;  //2
        }
    }
}

位运算求解

题中的意思就是从数字[0,n]之间的n+1个数字少了一个,而其他的数字都存在。

如果我们把这个数组添加从0~n的n+1个元素,就变成了数组中只有一个数出现了一次,其他数字都出现了2次,让我们求这个只出现一次的数字。这题使用位运算是最容易解决的,关于位运算有下面几个规律

1^1=0;

1^0=1;

0^1=1;

0^0=0;

也就说0和1异或的时候相同的异或结果为0,不同的异或结果为1,根据上面的规律我们得到

a^a=0;自己和自己异或等于0

a^0=a;任何数字和0异或还等于他自己

a ^ b ^ c=a ^ c^ b;异或运算具有交换律

有了这3个规律,这题就很容易解了,我们只需要把所有的数字都异或一遍,最终的结果就是我们要求的那个数字。来看下代码

java 复制代码
public int missingNumber(int[] nums) {
    int xor = 0;
    for (int i = 0; i < nums.length; i++)
        xor ^= nums[i] ^ (i + 1);
    return xor;
}

转换为PHP代码

php 复制代码
/**
 * @param Integer[] $nums
 * @return Integer
 */
function missingNumber($nums) {
    //位运算
    $xor = 0;                               //[3,0,1]
    for($i = 0; $i < count($nums); $i++){   // i=0;  nums[0] = 3; (0 + 1) = 1
        $xor ^= $nums[$i] ^ ($i + 1);       // xor =0 ^ 3 ^ 1   == 2
    }                                       // i=1;  nums[1] = 0; (1 + 1) = 2
    return $xor;                            // xor =2 ^ 0 ^ 2   == 0
                                            // i=2;  nums[2] = 1; (2 + 1) = 3
                                            // xor =0 ^ 1 ^ 3   == 2
}

求和

如果不缺那个数字的话,这个数组的所有数字可以组成一个等差数列,我们只需要根据公式求和,然后再减去数组中所有的数字即可,代码如下

java 复制代码
public int missingNumber(int[] nums) {
    int length = nums.length;
    int sum = (0 + length) * (length + 1) / 2;
    for (int i = 0; i < length; i++)
        sum -= nums[i];
    return sum;
}

转换为PHP代码为:

php 复制代码
/**
 * @param Integer[] $nums
 * @return Integer
 */
function missingNumber($nums) {
    //求和
    $length = count($nums);
    $sum = (0 + $length) * ($length + 1) / 2;   //等差数列求和公式为   (首项+末项)*项数 / 2
    for($i = 0; $i < $length; $i++){            //[3,0,1]  [0,1,2,3]  (0 + 3)*4 / 2
        $sum -= $nums[$i];                      //挨个减3,0,1,得到的结果为缺失的数字
    }
    return $sum;
}

方法来源:

作者:数据结构和算法

链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xnj4mt/?discussion=wMwk77

来源:力扣(LeetCode)

相关推荐
吱吱鼠叔13 分钟前
MATLAB方程求解:1.线性方程组
开发语言·matlab·php
菜鸟求带飞_13 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法
浅念同学15 分钟前
算法.图论-建图/拓扑排序及其拓展
算法·图论
是小Y啦31 分钟前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
程序猿练习生36 分钟前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode
liuyang-neu41 分钟前
力扣 42.接雨水
java·算法·leetcode
y_dd1 小时前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_631270401 小时前
标准c语言(一)
c语言·开发语言·算法
万河归海4281 小时前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记1 小时前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio