**题目:**给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0]
输出:3
示例 2:
输入:nums = [3,4,-1,1]
输出:2
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
解题思路:
本题目有几个要点:
1、首先要找到的是最小的正整数,因此可以对非正数进行处理。可以把非负数都用0替代,或者用大于n的数字代替。这里采用n+1替换。
2、原地哈希的一个重难点,就是在当前数组或者列表增加标记后,如何找到标记之前的数据。通过取相反数可以很好的解决这个问题。由于当前数组中都是正数,因此被标记后,取得相反数后得到了负数。在遍历的过程中,小于0则表示该位置被标记,通过取绝对值可以获得初始数据。
3、最后,通过遍历结果数组,找到第一个大于0(即没有被标记)的位置。该位置+1(数组下标从0开始,因此需要+1)就得到没有出现的最小正整数。
答案代码:
class Solution {
public int firstMissingPositive(int[] nums) {
int n = nums.length;
//负数用n+1代替
for (int i = 0; i < n; ++i) {
if (nums[i] <= 0) {
nums[i] = n + 1;
}
}
//进行哈希标记
for (int i = 0; i < n; ++i) {
int num = Math.abs(nums[i]); //通过绝对值取得初始数据
if (num <= n) { // <= n,则说明该数据本来就是正数
//替换成相反数
nums[num - 1] = -Math.abs(nums[num - 1]);
}
}
//遍历数组
for (int i = 0; i < n; ++i) {
//第一个大于0的数据,对应位置就是没有出现的最小正整数-1
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
}