Go语言题解LeetCode268丢失的数字示例详解
刘09k11 人气:0题目描述
原题链接 :
给定一个包含 [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 中的所有数字都 独一无二
进阶:你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?
思路分析
拿到这个题目,发现其是在[0,n]范围内给出n个数字,也就是说,这个是高度适配将数组进行排序的想法的。 对于完整的数组,其排序后应该是一个跟下标值完全一致的数组集合。 那么解法就很简单了,寻找第一个跟元素不匹配的下标,其就是缺失的数字;
AC 代码
class Solution: def missingNumber(self, nums: List[int]) -> int: nums.sort() for i in range(len(nums)): if nums[i] != i: return i return len(nums)
异或两遍 - 丢失的数字
解题思路
异或是一个可交换顺序的操作。同一个数字异或两遍等于零。
所以我们先求出数据的范围,直接找最大的数即可。 这里需要注意,如果最大的数字小于数组长度,则缺失的数字是最大的数字+1。
然后我们对 [0, n] 的所有数字累计异或一边,再对数组中的所有元素也异或一遍,最后就只剩下唯一一个没有出现的数字了。因为其他数字都出现了两遍。
代码
class Solution { public: int missingNumber(vector<int>& nums) { int n = 0; int ans = 0; for (auto num: nums) { n = max(n, num); ans ^= num; } if (nums.size() > n) n = nums.size(); for (int i = 0; i <= n; i++) { ans ^= i; } return ans; } };
C++ 排序二分、加减法、异或 - 丢失的数字
解题思路:
看到该题第一个想法就是二分法,首先给数字排序,然后通过mid值判断在左边还是在右边,nums[mid] == mid说明在右边,否则在左边,但是最后还要注意缺失的是最后一个数的情况,那么我们就要根据最后一个数进行判断,再进行返回,代码如下:
class Solution { public: int missingNumber(vector<int>& nums) { sort(nums.begin(), nums.end()); int left = 0, right = nums.size() - 1; while(left < right) { int mid = (left + right) / 2; if(nums[mid] == mid) { left = mid + 1; } else { right = mid; } } return (right == nums.size() - 1 && nums[right] == right) ? right + 1 : right; } };
但是显然没必要那么复杂,时间效率低,最全局的想法就是把所有下标加起来并且把数组都减去,剩下的就是丢失的数字,代码如下:
class Solution { public: int missingNumber(vector<int>& nums) { int total = 0; int i; for(i = 0; i < nums.size(); i ++) { total += i; total -= nums[i]; } total += i; return total; } };
异或的方法其实和加减方法实现方式一样,只是底层原理不同罢了,思路都是抵消掉相同的,留下唯一一个单独的,代码如下:
class Solution { public: int missingNumber(vector<int>& nums) { int total = 0; int i; for(i = 0; i < nums.size(); i ++) { total ^= i; total ^= nums[i]; } total ^= i; return total; } };
加载全部内容