题记:
给定一个包含 [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)