这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
一、题目描述
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1 :
输入 : [ 1, 2, 0 ] 输出 : 3 示例 2 :
输入 : [ 3, 4, -1, 1 ] 输出 : 2 示例 3 :
输入 : [ 7, 8, 9, 11, 12 ] 输出 : 1
提示:你的算法的时间复杂度应为O(n) ,并且只能使用常数级别的额外空间。
来源:力扣(LeetCode)
二、解题思路
- 题目要求具备O(n)复杂度,则不能先做排序处理;
- 因为是正整数数组,所以经过排序之后应该形如 [1,2,3,4,...,n] 数组 A。
- 如果入参数组经过“调整”后的数组 B 中,任意元素与 A 不匹配,则那个元素就是 缺少的最小的正整数。
- 此“调整”做法:尽可能将 1 放到数组的第 1 个位置,将 2 放到数组的第 2 个位置,以此类推。
- 最终从左到右遍历数组 B,找到第一个 索引 != 值-1 的值,即为答案。
三、参考代码
class Solution {
public int firstMissingPositive(int[] nums) {
// 异常输入检查&过滤
if (null == nums || 0 == nums.length) {
return 1;
}
int i = 0;
while (i < nums.length) {
int val = nums[i];
if (val <= 0 || val == i+1 || val > nums.length) {
// 不符合题意的异常值,直接跳过不处理
i++;
continue;
}
// 索引为 0 的位置应该放置 1,所以,索引为 val-1 的位置应该放 val
int index = val - 1;
// 提取 val-1 位置上的值
int tmpVal = nums[index];
// 将索引为 val-1 的位置置为 val
nums[index] = val;
if (val == tmpVal) {
// 重复值,置0表示缺失
nums[i++] = 0;
} else {
// 交换位置
nums[i] = tmpVal;
}
}
// 从左到右遍历“调整”后的数组,找到第一个 索引 != 值-1 的值
for (i = 0; i < nums.length; i++) {
if (nums[i] != i+1) {
return i+1;
}
}
return nums.length + 1;
}
}