题目
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

思路一:对数组排序,然后遍历,找到第一个是正数的索引下标。如果这个正数不是1,那我们就直接返回1。如果是1,我们就分析,如果后续相邻的元素之间的差不是0或1,我们就认为中间有跳跃的元素,那就返回当前元素的值+1。如果都是按顺序返回的,我们直接返回最后一个元素的值+1。
public int firstMissingPositive(int[] nums) {
// 排序
Arrays.sort(nums);
// 开始遍历的元素下标
int star = 0;
// 如果数组长度为1 要么返回1,要么返回2
if(nums.length == 1){
if(nums[0] == 1){
return 2;
}else {
return 1;
}
}
// 找到第一个正数
for(int i = 0; i < nums.length; i++){
if(nums[i] > 0){
star = i;
break;
}
}
// 如果第一个正数不等于1 就直接返回1,同时也防止了全是负数的情况
if(nums[star] != 1){return 1;}
// 如果相邻的两个数的差 既不是1 也不是0 说明中间有空的正数,返回前面一个数+1
else {
for(int i = star; i < nums.length-1; i++){
if(nums[i+1] - nums[i] != 1 && nums[i+1] - nums[i] != 0){
return nums[i]+1;
}
}
}
// 如果整个数组都是按顺序从1开始,中间没有跳跃,那就返回最大的那个数+1
return nums[nums.length-1]+1;
}
注释应该写的挺清楚了。
由于使用了sort,时间复杂度为O(nlogn)。

思路二:用Hashmap来做,把元素一一放进去。然后根据数组长度来找第一个不在哈希表中的元素。比如数组长度为10,我们从1到11遍历。这里说一下为什么是11。因为最差的情况就是全部元素都是顺序排序,即数组元素为1,2,3,4,5,6,7,8,9,10。这样保证了最后返回的是11。也就是说在数组长度+1的范围内,一定可以遍历到那个最小正数。
public int firstMissingPositive1(int[] nums){
HashMap<Integer,Integer> hm = new HashMap<>();
for(int i = 0; i < nums.length; i++){
hm.put(nums[i],i);
}
for(int i = 1;i <= nums.length+1; i++){
if(!hm.containsKey(i)){
return i;
}
}
return 1;
}
时间复杂度O(n)

emmmmm,但是为啥下降不到0ms呢。。。
498

被折叠的 条评论
为什么被折叠?



