leetcode41. 缺失的第一个正数(困难)

leetcode41. 缺失的第一个正数(困难)_第1张图片
leetcode41. 缺失的第一个正数(困难)_第2张图片
leetcode41. 缺失的第一个正数(困难)_第3张图片
自己的思路:将大于0的放到一个hash里面,然后从1开始找第一个不在hash里面的正整数,但是空间复杂度O(n),不满足题意。。
空间复杂度优化:由于ans只可能是1->n+1,所以可以考虑用原数组做hash。
step1:将数组中所有的负数和0改变为一个不可能为ans的正整数
step2:用负号标记法。i 在i-1的位置用’-'做标记,标记时注意不要标记两遍(等于没标记),在标记前判断该位置是正数才标记。
step3:依次遍历每个位置,return i + 1 最后不满足的话return n+1。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {

        int n = nums.size();
        for (int i = 0; i < n; ++i) { 
            if (nums[i] <= 0) nums[i] = n + 1;  
        }
        for (int i = 0; i < n; ++i) {
            long long tmp = abs(nums[i]); //
            if (1 <= tmp && tmp <= n && nums[tmp - 1] > 0)  //
            	nums[tmp - 1] = -nums[tmp - 1];
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) return i + 1;
        }
        return n + 1;
    }
};

易错点
1:遍历到后面有的可能被标记过了,所以为负数,要判断abs
2:标记两次即没标记,所以加&& nums[tmp - 1] > 0

你可能感兴趣的:(#,hash,leetcode41,缺失的第一个正数)