缺失数字,给定一个包含 [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)

相关推荐
DdddJMs__1354 分钟前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
汤米粥6 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
Fuxiao___7 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我12 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui11 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农1 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲1 小时前
浏览器是加载ES6模块的?
javascript·算法