給你一個數組,O(N)時間找出某些個數,這些題如果沒見過,還真不是很好想。做了這些題,我覺得有下面兩個個比較常見的思路:
1. 用兩個指標,可以從一邊開始,走某個距離停止,也可能是一頭一尾兩個指標,定義一種大小關係,他倆比較之後移動,直到相遇。
2. 用其他的輔助的資料結構,可能是hash表,可能是map,可能是棧或者隊列。這種通常用在訪問了現在的不能確定他們是不是有用,是不是能影響最後的結果,如果不先存下來,複雜度很可能就是N^2的了。
思路抽象了些,第二刷的時候我想能不能具體歸類一下。
這道題用到了第二種,用輔助的空間。數組沒排序,也沒告訴資料範圍,什麼雙指標肯定搞不定了,連續的數字可能離很遠,用自動排序好的map方便一些。map的值正好可以用來標記是否訪問過。關於什麼時候用什麼樣的輔助結構,應該也有比較系統的經驗,我道行還不夠深,不能很好的總結,先欠著。
實現的時候,從頭開始掃map,如果沒訪問過,就從左和右兩側查看,有個問題,如果用下標方法訪問map,那個鍵不存在的話,會自動插入一個,對這個問題是沒有影響的,因為自動插入的int為0,而且掃的順序是按照原來數組中的順序,因此map的規模變化了也沒關係,其他的問題要注意這個影響。
class Solution {public: int longestConsecutive(vector<int> &num) { int len = num.size(); if(len<=1) return len; int res = 1; map<int, int> seq; for(int i=0;i<len;i++){ seq[num[i]] = 1; } for(int i=0;i<len;i++){ if(!seq[num[i]]) continue; int tpres = 1; seq[num[i]] = 0; int left = num[i]-1; int right = num[i]+1; while(seq[left]){ seq[left--] = 0; tpres++; } while(seq[right]){ seq[right++] = 0; tpres++; } if(tpres>res) res = tpres; } return res; }};