題目分析
給出乙個字串,求出最長的沒有重複字元的子串。
解題思路
記錄法:首先我們必須知道怎麼判斷乙個子串的字元是否都只出現一次可以開乙個足夠大的布林陣列,然後每個字元是否出現記錄在對應ascll碼值的下標位置,初始化陣列都為0一旦遍歷到某個字元ch,若arr[ch]==1則表示ch已經在之前出現過,那我們我們就可以斷定這個子串不是題目要求的子串。
解法一:
通過列舉子串的左右下標直接列舉子串,然後對於這個子串用記錄法掃一遍。教育學習語言文字一n^2個子串,「掃一遍」複雜度是o(n)時,總體時間複雜度是o( ñ^ 3),雖然難以接受,但是我們可以在此演算法基礎上進行改進。
解法二:
對於乙個給定的子串起始點i,只我們關心它最遠能延伸到哪兒。所以我們只需要列舉子串起點i,此時清空記錄陣列,在不斷增大右邊界ĵ的同時更新記錄陣列,一直更新到串的右邊界,或者找到某乙個已經出現過的字元。那麼我們就可以斷定這個ĵ是起始點我對應的右邊界,更新答案即可。列舉左邊界時間複雜度o( n)時,延伸右邊界也是為o(n),總體時間複雜度為o(n ^ 2)。
解法三:
我們繼續改進解法二,如果對於某乙個起始點我我們已經找到了他的最遠右邊界ĵ,那麼在解法二中我們接下來需要列舉+ 1,然後又要開始重新延伸一遍尋找右邊界。但是我們發現串[i … j]的相比於串第[i + 1 … j]的只少了乙個字元[i],回憶我們記錄陣列的作用,我們完全可以擦除對於字元[i ]的記錄,然後對於i + 1的開始的串,它一直到ĵ必然是滿足的(因為即使增加乙個[i]字元都能滿足),所以我們可以在上一次的基礎上(j)往右延伸。
更一般的:
找到字串從[0]開始的最右邊界[j]時,使得子串[0 … j]的是合法的子串;
每次左邊界我加一,擦除[i]的記錄,右邊界從我時的右邊界[j]的開始延伸到[j 『],此時的第[i + 1 … j』]便是新的合法子串;
每次更新答案。
這個演算法中主要是兩個指標i,j,兩個指標都是從0開始最遠移動到n,並且在移動的過程中是一直增加的,故時間複雜度是o(變化(ⅰ)+變化(j))= o(2 * n)= o(n)。
總結:三解法其實的英文一種尺取法,尺取法一般的做法就是定左右兩個指標,每次移動左指標後更新右指標(當然兩者都必須是遞增的),故這個演算法的英文名也叫2指標。我們在解法三的末尾已經證明了尺取法的時間複雜度是o(n),那麼什麼樣的題能夠用尺取法優化呢?答案就是當我們稍大狀態的問題成立時比他的子狀態也必須成立,在此題中某如果個子串[i … j]的是合法的,那麼對於任意的i<=i』<=j』<=j,都有子串[i 『… j』]是合法的。
class solution ; int n = s.length ();題目分析int l = 0, r = 0;
while (r < n && !vis[s[r]])
int ans = r-l;
while (l < n)
ans = max (ans, r-l);
vis[s[l]] = 0;
l++;
}return ans;}};
給定乙個起始單詞和終結單詞和一些單詞,問能不能在每次隻變乙個字母的情況下,找出所有的從起始到終結單詞的變化路徑。
解題思路
首先對題目進行抽象,對於可以相互變化的單詞建立邊。
題目就變成了,給定乙個無向圖,求起點s到終點t的所有最短路徑。
最短路徑好求,只要bfs一遍就可以。比較難的部分在於求出所有的最短路徑。假設我們已經求出了dis(v),代表點v到起點的最短路徑長度,令l=dis(t)。
例子:令起點為ab,終點為cd,單詞為[ad,cd,cb,cd,aa]。 首先對單詞進行編號ad->0,cd->1,cb->2,cd->3,aa->4,ab->5
那麼可行邊是(0,1),(0,3),(0,4),(0,5),(1,2),(1,3),(2,3),(2,5),(4,5),起點為5,終點為1。 首先bfs得出dis(5)=0,dis(2)=1,dis(4)=1,dis(0)=1,dis(1)=2,dis(3)=2。
然後我們從點1出發,合法的邊有(1,0),(1,2),邊(1,3)不行因為dis(3)!=dis(1)-1
假設我們走了邊(1,0),下乙個能走的是邊(0,5),其他的都不合法,這時候dis(5)=0,找到了一條路徑(1,0,5)
假設我們走了邊(1,2),下乙個能走的是邊(2,5),其他的都不合法,這個時候dis(5)=0,找到了一條路徑(1,2,5)。
至此所有的路徑都找出來了。
class solution }}if(dis[end]==inf) return {};
cur.push_back(wordlist[end]);
genans(end,g,dis,wordlist);
for(int i=0;i> ans;
vectorcur;
void genans(int u,vector> &g,vector&dis,vector&wordlist)
for(int i=0;i}
};bool canchange(string &a,string &b) };
leetcode 四道shell程式設計題目
leetcode 192 統計詞頻 cat words.txt tr s n sort uniq c sort r awk tr s n 將空格替換成回車,每個單詞一行 sort 按字典序排序,保證重複的行相鄰 uniq c 去掉重複的行,c統計詞頻數 sort r 按逆序排序 awk 輸出leet...
leetcode 排序題目
merge k sorted lists insertion sort list sort list first missing positive sort colors 147.insertion sort list sort a linked list using insertion sort....
leetCode題目解析
給出兩個非空的鍊錶用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式儲存的,並且它們的每個節點只能儲存一位數字。如果,我們將這兩個數相加起來,則會返回乙個新的鍊錶來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。示例 輸入 2 4 3 5 6 4 輸出 7 0 8原...