开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情
LeetCode 268. 丢失的数字
一、题目描述:
给定一个包含 [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)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
这道题目看起来还是比较简单的我们来看一看吧。下面我来讲解一下我的思路:
先获取nums数组的长度,然后将数组排序,排序后遍历,找索引和值不相等的第一个值。来看一下这个思路可行吗?
看下面的AC代码似乎是可行的,但是用时和内存消耗都太多了吧!!!!
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是一次通过的,刚开始
return len(nums)写成了return 0,忽略了如果是最后一个数不在的话,此时遍历的话,遍历是能够通过的。 -
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
对于数组中 < len 的元素 i,让它和 nums[i] 进行调换,最后再遍历一边数组,nums[i] != i 的即为结果,若不存在返回 len。
public int missingNumber(int[] nums) { int len = nums.length; for (int i=0; i < len; i++) while (nums[i] < len && nums[i] != i) { int temp = nums[nums[i]]; nums[nums[i]] = nums[i]; nums[i] = temp; } for (int i=0; i < len; i++) if (nums[i] != i) return i; return len; }
三、AC 代码:
func missingNumber(nums []int) int { sort.Ints(nums) for i,v := range nums{ fmt.Println(i,v) if i != v { return i } } return len(nums) }执行用时:44 ms, 在所有 Go 提交中击败了8.20%的用户 内存消耗:6.2 MB, 在所有 Go 提交中击败了11.69%的用户 通过测试用例:122 / 122
四、总结:
此题无总结,巧妙的数学方法和位运算才是正道,实在不行,哈希集合也可以啊。
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。