缺失的第一个正数(java)
题目描述:
给你一个未排序的整数数组 nums
,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n)
并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0] 输出:3 解释:范围 [1,2] 中的数字都在数组中。示例 2:
输入:nums = [3,4,-1,1] 输出:2 解释:1 在数组中,但 2 没有。示例 3:
输入:nums = [7,8,9,11,12] 输出:1 解释:最小的正数 1 没有出现。
代码思路:
class Solution {
public int firstMissingPositive(int[] nums) {
// 如果数组为空或长度为0,直接返回1
if (nums == null || nums.length == 0) {
return 1;
}
// 对数组进行排序
Arrays.sort(nums);
// 如果数组的最小值大于1或数组中所有元素都小于0,缺失的最小正数就是1
if (nums[0] > 1 || nums[nums.length - 1] < 0) {
return 1;
}
// 初始化缺失的最小正数为数组最大值+1(假设数组内无缺失情况)
int temp = nums[nums.length - 1] + 1;
// 从头找到第一个非负数的索引
int i = 0;
while (nums[i] < 0) {
i++;
}
// 如果第一个非负数大于1,说明1是缺失的最小正数
if (nums[i] > 1) {
return 1;
}
// 遍历剩余的数组元素,寻找第一个缺失的正整数
for (; i < nums.length - 1; i++) {
// 检查相邻两个元素是否连续,并且跳过重复的元素
if (nums[i] + 1 != nums[i + 1] && nums[i] != nums[i + 1]) {
// 如果发现缺失的正整数,更新temp并退出循环
temp = nums[i] + 1;
break;
}
}
// 返回缺失的最小正整数
return temp;
}
}
要点:
-
特殊情况处理:
- 检查数组是否为空或长度为0。
- 判断数组中是否完全没有正整数。
-
排序:
- 将数组排序后,便于检查正整数是否连续。
-
查找第一个非负数索引:
- 通过循环找到数组中第一个非负数的位置。
-
判断是否缺失1:
- 如果第一个非负数大于1,则1是缺失的最小正整数。
-
遍历找缺失值:
- 跳过重复值并检查相邻元素是否连续。
-
返回结果:
- 如果未找到缺失值,返回假设的最大值+1;否则返回找到的缺失值。