这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战
leetcode 缺失的第一个正数
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0]
输出:3
示例 2:
输入:nums = [3,4,-1,1]
输出:2
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
```
解题:
要在一个数组中找到其中未出现的最小正整数,这个数组还是未排序的,并且数组元素是无符号的,还要求时间复杂度为O(N),空间复杂度为 O(1)。很多限制条件了,时间复杂度的话,O(2N)也是O(N),O(3N)也是O(N),空间只能使用常数个了。根据这些条件可以将数组元素放入到哈希表中(因为哈希表查找元素的时间复杂度为O(1)),从1开始依次判断这个数是否在哈希表中,但是使用另外的哈希表就不满足空间复杂度的要求了,所以可以考虑直接使用原来的数组,将原数组当一个哈希表来使用,来记录一下状态。首先对于长度为L的数组,那这个最小的正整数肯定在[1,L+1]里面,数组只能有L个的元素,如果1到L的整数都出现了,那最小正整数就是L+1了,否则肯定有一个1到L的最小正整数没在数组里面。然后我们遍历数组元素,因为数组可能会有负数,所以得先将负数值都转成L+1,因为这些负数是不在[1, L]中的,可以不考虑,然后在遍历数组获取元素判断是否在[1,L]范围内,如果在那就将这个数+1的下标位置的元素改为负数,那么一直到最后再查询遍历数组元素,如果数组元素都是负数那最小正整数就是L+1,否则就是数组第一个正数的位置下标+1。
```js
class Solution {
public int firstMissingPositive(int[] nums) {
int len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] <= 0) {
nums[i] = len + 1;
}
}
for (int i = 0; i < len; i++) {
int num = Math.abs(nums[i]);
if (num <= len) {
nums[num - 1] = -Math.abs(nums[num - 1]);
}
}
for (int i = 0; i < len; i++) {
if (nums[i] > 0) {
return i + 1;
}
}
return len + 1;
}
}