zoukankan      html  css  js  c++  java
  • leetcode problem 41 -- First Missing Positive

    Given an unsorted integer array, find the first missing positive integer.

    For example,
    Given [1,2,0] return 3,
    and [3,4,-1,1] return 2.

    Your algorithm should run in O(n) time and uses constant space.

    题意:

      给定了一个无序数组,要求找到第一个缺失的正整数.如1,2,4,5的第一个缺失的正整数是3.要求时间复杂度为o(n) 空间复杂度为o(1)

    思路:

      第一种是排序,时间复杂度为O(nlgn) 不行

      第二种是hash查找  对每一个数字都用额外空间找到正确的位置. 然后一次遍历找到第一个缺失的正整数.  时间复杂度为O(n)  但是空间复杂度为O(n) 也不符合题目要求

      第三种直接在输入数组上进行交换操作, 使得每个数字通过交换能在正确的位置上.如3,1,7,2 这组数字第一次交换后得到7,1,3,2   数字3放置在了正确的位置.

        这种时间复杂度为O(n)  而且只需要常数辅助空间.  但我认为这种方法依然不复合题目要求,因为它破坏了原始数组.  它其实也类似于hash, 需要O(n)的空间,只不过这O(n)的空间借用了原始输入数组上的.

      目前我还没找到即不破坏原始数组,空间复杂度又为O(1)的方法

    代码1(hash法):

      

    class Solution {
    public:
        int firstMissingPositive(vector<int>& nums) {
            if (nums.size() == 0)
                return 1;
            auto it_max = std::max_element(nums.begin(), nums.end());    
            auto it_min = std::min_element(nums.begin(), nums.end());
    
            vector<bool> vec(*it_max - *it_min, false);
            for (auto elem : nums) 
                vec[elem - *it_min] = true;
            for (auto it = 1; it <= *it_max; ++it) {
                if (it < *it_min || (it > 0 && !vec[it - *it_min]))
                    return it;
            }    
            return *it_max > 0 ? *it_max + 1 : 1;
        }
    
    private:
    };

    代码2(直接在原数组上进行交换, 空间代价为o(1))

    class Solution {
    public:
        int firstMissingPositive(vector<int>& nums) {
            if (nums.empty())
                return 1;
            auto begin = getFirstPositivePos(nums);
            if (*begin < 0)
                return 1;
            for (auto it = begin; it != nums.end(); ) {
                auto realPos = begin + *it - 1;
                if (realPos < nums.end() && realPos != it && *realPos != *it)
                    iter_swap(it, realPos);
                else
                    ++it;
            }
            int index = 1;
            for (auto it = begin; it != nums.end(); ++it, index++) {
                if (index != *it)
                    return index;
            }
            return index;
        }
    
    private:
        vector<int>::iterator getFirstPositivePos(vector<int>& nums) {
            auto first = nums.begin();
            auto last = nums.end()-1;
            while (true) {
                while (first < last && *first <= 0 ) 
                    ++first;
                while (first < last && *last > 0)
                    --last;
                if (first < last)
                    iter_swap(first, last);    
                else
                    break;
            }
            return first;
        }
    };
  • 相关阅读:
    Java中的I/O 线程 网络
    20169214 2016-2017-2 《网络攻防实践》第六周学习总结
    20169214 2016-2017-2 《网络攻防实践》第五周学习总结
    20169214 2016-2017-2 《移动平台开发实践》第五周学习总结
    20169214 2016-2017-2 《移动平台开发实践》第四周学习总结
    20169214 2016-2017-2 《网络攻防实践》第四周学习总结
    20169214 2016-2017-2 《网络攻防实践》第三周学习总结
    20169214 2016-2017-2 《移动平台开发实践》第三周学习总结
    20169214 2016-2017-2《网络攻防实践》第二周学习总结
    Android开发设计 实验报告
  • 原文地址:https://www.cnblogs.com/lysuns/p/4479212.html
Copyright © 2011-2022 走看看