【趣味算法題】找到缺失的最小正整數

【題目描述】ios

有一個隨機序列的數組,找到其中缺失的最小正整數算法

舉例以下,在[1,  2,  0] 中,該最小正整數應爲3數組

在[3,  4,  -1,  1]中,該最小正整數應該爲2post

 

【解題思路】spa

若是容許開闢任意大小的空間,易得用桶的思想能夠解決這題code

簡單的說,開闢一個數組,從1掃過來若是不存在那麼break輸出便可blog

 

若是對空間的要求是O(1) ,利用桶排序接下來有一個很是漂亮的解決方法:排序

 

咱們能夠把每一個數字放在其該放的地方。什麼意思呢?leetcode

好比 A[0] = 1, A[1] = 2, A[2] = 3, 諸如此類get

而後放好以後從1掃過來若是不存在那麼break輸出便可

 

關鍵就是在於,如何將每一個數字放在其該放的地方呢

方法以下:

 

若是 A[i] 是合法的數 (合法的意思是 A[i] > 0 && A[i] < n)

那麼A[i] 應該放的位置爲 A[A[i] - 1] 纔對。

若是固然的 A[i] 不在 A[A[i] - 1] 的話,那麼swap (A[i], A[A[i] - 1]) 便可

 

這到題目就是利用這個思路解決,若是碰到重複出現的數字也是能夠解決 :)

 

【算法效率分析】

O(1) space, and O(n) time

 

 

My Source Code:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

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

        for (int i = 0; i < nums.size (); ++i) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }

        return nums.size () + 1;
    }

    void bucket_sort (vector <int> & nums) {
        for (int i = 0; i < nums.size (); ++i) {
            while (nums[i] != i + 1) {
                if (nums[i] < 0 || nums[i] > nums.size () || \
                    nums[i] == nums[nums[i] - 1]) {
                        break;
                    }
                cout << "i = " << i << "\t" << nums[i] << "\t" << nums[nums[i] - 1] << endl;
                swap (nums[i], nums[nums[i] - 1]);
                cout << "\t";
                for (int j = 0; j < nums.size (); ++j) {
                    cout << nums[j] << " ";
                }
                cout << endl << endl;
            }
        }
    }
};

int main () {

    Solution sl;
    vector <int> vc;
    vc.push_back (3);
    vc.push_back (-4);
    vc.push_back (2);
    vc.push_back (1);
    vc.push_back (5);

    cout << sl.firstMissingPositive (vc);

    return 0;
}

 

推薦閱讀文章:

三種線性排序算法 計數排序、桶排序與基數排序

https://www.byvoid.com/blog/sort-radix/

相關文章
相關標籤/搜索