【每日一題】LeetCode. 128. 最長連續序列

每日一題,防止癡呆 = =

一、題目大意

給定一個未排序的整數數組,找出最長連續序列的長度。

要求算法的時間複雜度爲 O(n)。
在這裏插入圖片描述
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-consecutive-sequence

二、題目思路以及AC代碼

最開始看到這道題還以爲是最長上升子序列呢 = =,仔細一看,原來不是。

思路一

先說一下我自己想到的思路,最後發現還是比官解複雜一點,但感覺出發點是一樣的。題目要求求數組中連續的序列,那麼我們就可以在遍歷到一個數x的時候,查看x向右可以最遠到哪個數,x向左最遠可以到哪個數,這樣的話,我們只要枚舉這些數,然後找到最長的序列即可,其中我們在查看某個數是否在數組中,可以提前用unorder_map去保存。

當我們在枚舉這些數列的時候,其實有點並查集的意思,如果我遍歷x的時候,發現y在x的連續數列中,那麼x肯定也在y的連續數列中,那麼這兩個連續數列就沒必要遍歷兩次了,所以我又採用了一個unordered_map來記錄該數是否已經遍歷過了,這樣整體每個數只會被遍歷一次,則複雜度爲O(n)。

思路二

做完之後,我去看了看題解的思路,和我的思路類似,感覺是又優化了一次。我的思路中,每次需要找一個數左右兩邊的邊界,而題解中將該數自身作爲左邊界,只去找右邊界,而這樣也不需要另外一個unordered_map來記錄是否遍歷過了,因爲如果當前數x在數組中存在x-1,則它就沒必要遍歷,因爲遍歷到x-1的時候,肯定會遍歷它,所以在空間上減少了一個unordered_map的空間,在時間上感覺兩種方法是差不多的。

AC代碼

思路一:

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_map<int, bool> contains;
        unordered_map<int, bool> vis;

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

        int res = -1;
        for (int i=0;i<n_size;i++) {
            if (vis[nums[i]]) continue;

            int cnt = 1;
            int num = nums[i] - 1;
            // 向左找
            while (contains[num]) {
                vis[num] = true;
                cnt++;
                num--;
            }
            // 向右找
            num = nums[i] + 1;
            while (contains[num]) {
                vis[num] = true;
                cnt++;
                num++;
            }
            
            res = max(res, cnt);
        }

        return res;
    }
};

思路二:

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_map<int, bool> contains;

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

        int res = -1;
        for (int i=0;i<n_size;i++) {
            if (contains[nums[i]-1]) continue;

            int cnt = 1;
            int num = nums[i] + 1;
            while (contains[num]) {
                cnt++;
                num++;
            }
            
            res = max(res, cnt);
        }

        return res;
    }
};

如果有問題,歡迎大家指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章