掘金团队号上线,助你 Offer 临门! 点击 查看大厂春招职位
一、题目描述:
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?
示例 1:
输入:nums = [1,2,0]
输出:3
示例 2:
输入:nums = [3,4,-1,1]
输出:2
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
题目地址:leetcode-cn.com/problems/fi…
二、思路分析:
首先的思路是先进行排序,然后再进行查找,时间复杂度的瓶颈就在排序上。如果要达到 O(n)的时间复杂度的话,能选择的排序算法貌似也就只有桶排序了。
数组的下标是有序的,可以利用数组的下标。
我们排序的最终目标是: nums[i] = i-1
然后遍历整个数组,如果不符合上述目标的位置是 x,没有出现的最小整数即是 x+1。
下面简单说一下怎么对数组进行排序,如果还是不太明白,可以先学习下如何实现对0-9进行桶排序
先把 nums[0]位置的数拿出来 放到temp里,然后看一下temp 应该放到哪个位置(内循环)。
然后把这个位置的数与temp交换一下,然后再看一下temp应该放到哪个位置。
直到所有的temp没有地方放了,temp的值已经超数组下标了。就结束循环。
然后再去拿nums[1]。
三、AC 代码:
public int firstMissingPositive(int[] nums) {
if (nums.length == 0) {
return 1;
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] - 1 < 0 || nums[i] - 1 > nums.length - 1) {
continue;
}
while (nums[i] - 1 >= 0 && nums[i] - 1 < nums.length && nums[i] - 1 != i) {
if (nums[nums[i] - 1] == nums[i]) {
break;
}
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] - 1 != i) {
return i + 1;
}
}
return nums.length + 1;
}
四、总结:
需要注意数组下标越界的问题。