zoukankan      html  css  js  c++  java
  • LeetCode First Missing Positive

    class Solution {
    public:
        int firstMissingPositive(int A[], int n) {
            if (A == NULL || n < 1) return 1;
    
            size_t len = (size_t)n + 1;
            vector<bool> bits(len, false);
            for (int i=0; i<n; i++) {
                if (A[i] < 0 || A[i] > n) continue;
                bits[A[i]] = true;
            }
            int miss = 1;
            while (miss <= INT_MAX) {
                if (!bits[miss]) return miss;
                if (miss == INT_MAX) {
                    cout<<"no missing positive"<<endl;
                    break;
                }
                miss++;
            }
            bits.clear();
            return 0;
        }
        
        int firstMissingPositive2(int A[], int n) {
            if (A == NULL || n < 1) return 1;
    
            unordered_map<int, int> mark;
            for (int i=0; i<n; i++) {
                mark[A[i]] = 1;
            }
    
            int miss = 1;
            while (miss <= INT_MAX) {
                if (mark.find(miss) == mark.end()) return miss;
                if (miss == INT_MAX) {
                    cout<<"no missing positive"<<endl;
                    return 0;
                }
                miss++;
            }
            return miss;
        }
        
        int firstMissingPositive3(int A[], int n) {
            if (A == NULL || n < 1) return 1;
    
            for (int i = 0; i<n; i++) {
                if (A[i] <= 0) A[i] = n + 1;
            }
            for (int i=0; i<n; i++) {
                int cur = A[i] < 0 ? -A[i] : A[i];
                if (cur <= n) A[cur - 1] = A[cur - 1] < 0 ? A[cur - 1] : -A[cur - 1];
            }
            int miss = 1;
            for (int i=0; i<n; i++) {
                if (A[i] > 0) break;
                miss++;
            }
            return miss;
        }
    };

    心烦,因为要找出数组A[n]中第一个缺失的整数,如果数组中有元素大于n那么这个数组必定至少缺失了一个数,因为如果A[n]包含[1,n]那么刚刚n个数,一个不少,且每个数小于n,如果某个元素大于n了,则中间肯定有间隙存在,否则元素个数将大于n。利用这一特征我们可以把负数和大于n的数都置为n+1这样在下一次扫描时可以忽略它们。

    解法三存在一个问题,当n=INT_MAX且有负数存在时会出错。

    第二轮:

    解法三应该是从disscus上搞过来的,这个跟使用常数空间找一个无序数组(数组元素范围小于长度值)中的重复值类似,可以使用负数作为标记。实际上是使用了每个元素的符号位这样的一系列1bit的存储空间。反正已经将数组破坏掉了,还可以这样写避免数值溢出:

     1 class Solution {
     2 public:
     3     int firstMissingPositive(vector<int>& nums) {
     4         int len = nums.size();
     5         int idx = 0;
     6         for (idx = 0; idx < len; idx++) {
     7             if (nums[idx] == 1) {
     8                 break;
     9             }
    10         }
    11         if (idx == len) {
    12             return 1;
    13         }
    14         
    15         for (int i=0; i<len; i++) {
    16             nums[i] = max(1, nums[i]);
    17         }
    18         
    19         for (int i=0; i<len; i++) {
    20             idx = abs(nums[i]) - 1;
    21             if (idx >= len) {
    22                 continue;
    23             }
    24             if (nums[idx] > 0) {
    25                 nums[idx] = -nums[idx];
    26             }
    27         }
    28         idx = 0;
    29         while (nums[idx] < 0 && idx < len) idx++;
    30         return idx + 1;
    31     }
    32 };

    把小于等于0的数全部置为1,当然首先要检测一下1是否存在。

  • 相关阅读:
    java 基础学习 关键字、标识符、常量、进制、有符号表示法、变量、数据类型小节
    java 基础学习 异常的处理和自定义 学习总结
    正则表达式应用--实例应用
    ArrayList:去除集合中字符串的重复值 LinkedList:去除集合中自定义对象的重复值
    java IO流中文件,图像,视频,拷贝总结
    递归算法学习心得与体会
    如何打印身份证的正反面
    添加div间距
    Junit:NoSuchMethodError runLeaf runChild
    Ajax:async
  • 原文地址:https://www.cnblogs.com/lailailai/p/3859215.html
Copyright © 2011-2022 走看看