41. 缺失的第一个正数 原地哈希

原题

题意大概是给你一个无序数组,希望你找出排序过后,数组从小到大数,第一个没有找到的正数。

例如,nums = [1,2,0],答案应该是3。

因为有时间O(n) 和 空间常数级别的要求,所以像是HashMap、Set、排序之类的操作都不行。O(n)的时间复杂度只能支撑的起遍历数组(或者二分)。
空间常数级别的要求又限制了不能随便根据数组大小开数据结构,所以最多只能是定义变量或者原地修改。

如果时间复杂度允许的话,最简单的方法是排序过后,遍历第一个 位置 i 上的值 不等于 i + 1 那个数就是答案。想了一下,快排的时间复杂度在于不断的折半排序,每一次折半的数组都不是一个有序数组。但如果说,这个数组所有的数组一下就能找到相应的位置的话,排序时间复杂度就下降了。

所以采用递归的方法手动进行排序,将时间复杂度降到O(n),即每一个位置都只排序一次。

排序过程中,如果当前位置 location 上的值并不是 location + 1 说明需要排序,那 nums[location]上的值理论上应该在数组位置的 nums[location] - 1 这个位置上,那么就把nums[location] 上的值交换过去,这个位置就算排好序了,接下来只要再对交换位置上的数在排序,就能得到在特定条件下,O(n)时间复杂度就能排好序的一个数组。

最后,再遍历一遍数组,找第一个不满足条件数的,就是答案。

    public int firstMissingPositive(int[] nums) {
        for(int i = 0; i < nums.length; i++) {
            // 位置正确
            if(nums[i] == i + 1) {
                continue;
            }
            // 位置不正确 不断交换
            exchange(i, nums[i], nums);
        }
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] != i + 1) {
                return i + 1;
            }
        }
        return nums.length + 1;
    }

    public static void exchange(int initLocation, int val, int[] nums) {
        // val 应该存在的位置 location
        int location = val - 1;
        if(location < 0 || location >= nums.length) {
//            数组越界 不换
            return;
        }
        // tmp val 应该存在的位置 上的值
        int tmp = nums[location];
        if(tmp <= 0 || tmp > nums.length) {
            nums[location] = val;
            nums[initLocation] = tmp;
        }
        if(tmp == location + 1) {
            return;
        } else {
            nums[location] = val;
            exchange(initLocation, tmp, nums);
        }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值