0
点赞
收藏
分享

微信扫一扫

41缺失的第一个正数 (哈希表)

一叶轻舟okok 2022-02-22 阅读 46

**题目:**给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3
示例 2:

输入:nums = [3,4,-1,1]
输出:2
示例 3:

输入:nums = [7,8,9,11,12]
输出:1

解题思路:
本题目有几个要点:
1、首先要找到的是最小的正整数,因此可以对非正数进行处理。可以把非负数都用0替代,或者用大于n的数字代替。这里采用n+1替换。
2、原地哈希的一个重难点,就是在当前数组或者列表增加标记后,如何找到标记之前的数据。通过取相反数可以很好的解决这个问题。由于当前数组中都是正数,因此被标记后,取得相反数后得到了负数。在遍历的过程中,小于0则表示该位置被标记,通过取绝对值可以获得初始数据。
3、最后,通过遍历结果数组,找到第一个大于0(即没有被标记)的位置。该位置+1(数组下标从0开始,因此需要+1)就得到没有出现的最小正整数。

答案代码:

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        //负数用n+1代替
        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) { // <= n,则说明该数据本来就是正数
                //替换成相反数
                nums[num - 1] = -Math.abs(nums[num - 1]);
            }
        }
        //遍历数组
        for (int i = 0; i < n; ++i) {
            //第一个大于0的数据,对应位置就是没有出现的最小正整数-1
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }
}
举报

相关推荐

0 条评论