每天一道LeetCode-----计算最长的元素连续序列长度
Longest Consecutive Sequence
原題鏈接Longest Consecutive Sequence
給定一個序列,尋找最長的連續元素序列,對于示例而言,給定的序列中存在1,2,3,4這四個元素,所以最長的連續元素序列的長度為4
要求就是給定類似的序列,返回長度,要求時間復雜度是O(n)
本題中在遍歷到一個元素時,有三種情況值得考慮
- 當前元素是連續序列的左邊界,也就是結果中的最小值
- 當前元素是連續序列的右邊界,也就是結果中的最大值
- 當前元素是中間的某個元素,這個元素可以將左右兩部分連在一起
直觀上判斷也是第三種情況最為合理,假設當前遍歷到元素n,同時假設i,i+1,i+2,...,n?1和n+1,n+2,...,j這兩個連續序列已知,那么當前遍歷到的這個n就可以將左右兩部分連成i,i+1,...,n,...,j
而對于本題而言,不需要知道左右兩部分的序列是什么,只需要知道左右兩部分的長度即可,那么可以采用map記錄這樣的信息,規則是
- map[n]代表以n為左邊界和右邊界的連續序列中最長的那個的長度
對于上面的例子,可以通過map[n-1]得知i,i+1,i+2,...,n?1的長度,也可以通過map[n+1]得知n+1,n+2,...,j的長度,而當n將左右兩邊連起來后的總長度就是map[n?1]+1+map[n+1]
當計算出i,i+1,…,n,…,j這個序列的長度后,需要改變map[i]和map[j]的值,令其記錄這個序列的長度即
map[i]=map[j]=map[n?1]+1+map[n+1]
其實本質上就是每當獲得一個連續的序列,都將這個序列左右兩個邊界的元素在map中的值設置為這個序列的長度,當下次不管是從左邊繼續合并還是從右邊繼續合并都可以獲得這個序列的原先長度
代碼如下
class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_map<int, int> hash;int len = 0;for(auto& n : nums){/* 只有當元素n在之前沒有遍歷過的時候才判斷是否可以合并序列 */if(hash.find(n) == hash.end()){/* 獲取n左右兩個序列的長度,如果不存在則使用0代替 */int left = hash.find(n - 1) != hash.end() ? hash[n - 1] : 0;int right = hash.find(n + 1) != hash.end() ? hash[n + 1] : 0;/* 計算合并后的長度 */int sum = left + 1 + right;/* 在左右兩邊界處記錄合并之后的長度,這一步和上面獲取left和right是對應的,只有在兩邊界都設置才可以從任意一遍都獲取序列的長度 */hash[n - left] = hash[n + right] = sum;/* 設置不需要設置成sum,只需要設置一個值用于記錄n已經遍歷過 */hash[n] = sum;/* 更新最大值 */len = std::max(len, sum);}}return len;} };本題在于利用序列的左右邊界獲取序列的長度,以當前遍歷的元素為中間銜接元素將左右兩個序列合并成一個,這就需要能夠獲取左右兩個邊界的長度
總結
以上是生活随笔為你收集整理的每天一道LeetCode-----计算最长的元素连续序列长度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----计算二
- 下一篇: 每天一道LeetCode-----计算二