力扣题目
解题思路
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 没有出现。
解题思路:
算法思路:
- 首先,将数组中所有小于等于 0 的数替换为
n + 1
,这样处理是为了将非正整数与正整数区分开来。 - 然后,对于每个正整数,通过其值作为索引,将对应位置的数取绝对值并变为负数。这样做的目的是标记已经出现过的正整数。
- 最后,遍历数组,如果某个位置的数仍然是正数,那么该位置的索引加 1 就是第一个缺失的正整数。如果整个数组都没有找到这样的位置,说明缺失的正整数是
n + 1
。
代码分析:
- 在
for
循环for (int i = 0; i < n; ++i)
中,将非正整数替换为n + 1
。- 例如,如果
nums[i] = -3
,则将其改为n + 1
。
- 例如,如果
- 接着,另一个
for
循环for (int i = 0; i < n; ++i)
,通过取绝对值和索引操作标记已出现的正整数。- 比如,如果
nums[i] = 2
,则将nums[1]
变为负数-nums[1]
。
- 比如,如果
- 最后一个
for
循环用于查找第一个未被标记的位置。- 假设数组为
[1, -2, 3, 4]
,经过前面的操作,最后遍历会发现nums[1]
大于 0 ,所以返回1 + 1 = 2
,即 2 是第一个缺失的正整数。
- 假设数组为
这种方法的时间复杂度为 ,空间复杂度为 ,是一种高效的解法。
java代码:
package org.example.mouth7.today23;
public class Leetcode41 {
public static void main(String[] args) {
int[] nums = {-3, 2, 4, 1};
System.out.println(new Leetcode41().firstMissingPositive(nums));
}
public int firstMissingPositive(int[] nums) {
int n = nums.length;
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) {
nums[num - 1] = -Math.abs(nums[num - 1]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项