题记:
给定一个包含 [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)
解题方法
自己想的:
补全数组,再比较差集即可
代码为:
/*** @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代码:
/*** @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个规律,这题就很容易解了,我们只需要把所有的数字都异或一遍,最终的结果就是我们要求的那个数字。来看下代码
public int missingNumber(int[] nums) {int xor = 0;for (int i = 0; i < nums.length; i++)xor ^= nums[i] ^ (i + 1);return xor;
}
转换为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) = 2return $xor; // xor =2 ^ 0 ^ 2 == 0// i=2; nums[2] = 1; (2 + 1) = 3// xor =0 ^ 1 ^ 3 == 2
}
求和
如果不缺那个数字的话,这个数组的所有数字可以组成一个等差数列,我们只需要根据公式求和,然后再减去数组中所有的数字即可,代码如下
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代码为:
/*** @param Integer[] $nums* @return Integer*/
function missingNumber($nums) {//求和$length = count($nums);$sum = (0 + $length) * ($length + 1) / 2; //等差数列求和公式为 (首项+末项)*项数 / 2for($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)