LeetCode41.缺失的第一个数
【LeetCode】41.缺失的第一个数
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?
思路:哈希表
对于一个长度为N的数组,其中没有出现的最小正整数只能在[1,N+1]中,因为如果[1,N]都出现了,那么答案是N+1,否则答案就是[1,N]中没有出现的最小正整数。将所有在[1,N]范围内的数放在哈希表,就可得到最终答案。
算法过程:
- 将数组中所有小于等于0的数修改为N+1;
- 遍历数组中的每一个数x,可能已经被打了标记(表示为负号),因此原本对应的数为|x|(||为绝对值符号),如果|x|属于[1,N]范围,那么就给数组中的第|x|-1个位置的数添加一个负号。
- 遍历完成后,如果数组中的每一个数都是负数,那么答案是N+1,否则答案是第一个正数的位置加1.
代码:
class Solution { // 哈希表法 public int firstMissingPositive(int[] nums) { // 首先将数组中所有负数变为N+1(N为数组的长度) int len = nums.length; for(int i=0; i<nums.length; i++){ if(nums[i] <= 0){ nums[i] = len+1; } } // 遍历数组,如果x在[1,N]范围内,则打上标记,本题【标记】表示为【负号】 for(int i=0; i<nums.length; i++){ int num = Math.abs(nums[i]); if(num <= len){ nums[num-1] = -Math.abs(nums[num-1]); } } // 遍历数组,第一个正数位置为最终答案,如果全为负数,则答案为N+1; for(int i=0; i<nums.length; i++){ if(nums[i] > 0) return i+1; } return len+1; } }