leetcode41. 缺失的第一个正数

传送门

题目:给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
输入: [1,2,0] 输出: 3
输入: [3,4,-1,1] 输出: 2

方法1. 排序之后 顺序遍历 时间: 取决于排序算法 空间: 常数
方法2. 构造Hash表 时间: O(n) 空间: O(n)

注意Hash表不一定要用hashMap 可以先找数组的规律: 第一个缺失值(ans)最大是len+1
因为: 1 2 3 4 长度是4 ans是5,如果还有一种情况使得ans>5 那么5一定在数组中出现,那么5会替换1234中的任一个, 假如替换2, 那么2就变成第一个缺失值了,轮不到5了。
所以hash表可以设置 new int[len + 1] 就行

方法3. 数组元素的符号(+、-) 充当hash,只是改变原有值的正负号,绝对值没有改变

基于方法2可知: ans不会超过len+1 算法流程:

  1. 将负数,零,和大于 len+1 的数替换为 len+1。(去除无用的值,还能保证使用nums[i]做索引不会越界)
  2. 遍历数组。当前值num的绝对值|num|作为索引index,如果index<=len 令nums[index-1] 的值变为负值
  3. 再次遍历数组。返回第一个正数元素的索引+1。如果提前没有返回 说明ans是len+1。

第2步: 之所以nums[i]取绝对值, 是因为可能提前被置为负数了, 之所以不是取反,因为可能有重复偶数个的num

在第2步结束,nums[i] < 0 说明 i+1 出现了

第3步: 之所以返回索引+1 是因为改变的是nums[index-1] ,index索引左移了一位 保证0索引位置也被考虑

 public int firstMissingPositive(int[] nums) {
    int len = nums.length;
    for (int i = 0; i < len; ++i) {
        if (nums[i] <= 0 || nums[i] > len + 1)
            nums[i] = len + 1;
    }
    for (int num : nums) {
        int index = Math.abs(num);
        if (index <= len) 
            nums[index - 1] = -Math.abs(nums[index - 1]);
    }
    for (int i = 0; i < len; ++i)
        if (nums[i] > 0) return i + 1;
    return len + 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值