演算法之字串題型總結

2021-09-22 21:31:30 字數 3215 閱讀 5393

1.字串的旋轉

給定abcdef,例如把字串的前三個字元移動到後面。形如:defabc!

解法一:暴力法

每次所有字串向前移動一位,移動m次即可。但是複雜度為o(mn)

解法二:三步反轉法(模擬結構的對稱性)

通過m把字串分割成兩個字串,然後對這兩個字串分別反轉。最後在對字串整體反轉。

abcdef--  ba fedc  --  cdef ab

擴充套件:對輸入的英文單詞進行反**"i am a student." 變為 "student. a am i"!

是不是只要對每個單詞翻轉一次,在對整體翻轉一次不就行了。

2.字串的包含

給定長字串a和短字串b,要b中的元素在a中都出現過!

解法一:暴力法

列舉短字元b,判斷在a中是否出現過。時間複雜度為o(m*n)

解法二:排序+暴力法

先對a和b字元排序,然後列舉b,只要a的字元大於b的字元那麼就可以判斷不包含,如果字元相等就下乙個b字元,小於就找下乙個a字元。

解法三:hash表(類似了計數排序方法)

把所有a字元都用hash表儲存(用長度26的陣列簡單來模擬),然後遍歷b字元進行查詢。時間o(m+n)!

擴充套件:給定兩個串a和b,問b是否是a的子串的變位詞。例如輸入a = hello, b = lel, lle, ello都是true,但是b = elo是false。

思路: 比如b的長度是3,則考察a[0..2], [1..3],[2..4]是否和b是變位詞,需要hash表進行更新元素,

擴充套件:第乙個只出現一次的字元?

思路一:暴力法是對每乙個字元查詢是否出現過,時間為n的平方;

思路二:雜湊表可以進行加速線性時間可以完成;

3.字串的全排列

輸入字串「abc」,按字典序排列,輸出所有排列後的字串"abc","acb","bac","bca"......

解法一:遞迴實現 

每次固定乙個位置,然後遞迴下去(第乙個位置,第二個.....第n個),第乙個位置可放n個,第二個可放n-1個,最後乙個放乙個。使用交換元素的思路,要注意交換後得交換回去復原!

字串有重複的時候,當前元素只要沒有與之前對應的元素相等那麼就可以交換,否則不可以,因為start位置的元素已經交換過了這個元素!

4.字串轉化成整數

直接寫出**容易:從左向右使用n = n*10 + c公式即可!

ps:要判斷空,要判斷正負號,要判斷字串是否合法,要判斷是否會溢位。

5.判斷字元陣列是否所有字元都出現過一次

思路一:使用雜湊表來判斷是否出現了重複。

思路二:進行排序但是題目要求空間複雜度為常量,所以快排(遞迴和非遞迴版本都需要空間),歸併兩個較快的使用不了,只能使用非遞迴的堆排序了。

6.字串的調整與替換

把字串的空格替換為"%20",設右半區足夠大

思路:遍歷左半區,計算出最終一共需要的位置,然後逆序遍歷進行填補。

擴充套件:字串中有字元"*"要把該字元全部移動到前面。

因為不用擴充字元,所以直接逆序遍歷進行判斷,再把前面的空字元填補成"*"。

7.陣列中兩個字元的最小距離

思路:需要兩個指標和乙個遍歷指標,分別記錄字元最近一次出現的位置,每更新一次位置就計算一次最短距離。

8.新增最少字元使字串整體都是回文子串

思路:設dp(i,j)代表字元i到j為回文串的最少新增字元數。需要注意i到j只有乙個字元,i到j有兩個字元的特殊情況,i到j多於兩個字元為一般情況, if s(i)=s(j) dp(i,j)=dp(i+1,j-1)  if 不等,需要新增乙個字元給i還是j找乙個最小的即可,dp(i,j)=min(dp(i+1,j),dp(i,j-1))+1

擴充套件:如果需要列印出來構造的回文串,需要逆序遍歷構造出來,注意判斷在左邊加字元還是在右邊加字元。

9.回文最少分割數

思路一:使用暴力遞迴,每個位置分和不分,返回分割最少的即可,如果分那麼前一部分必須是回文串。

思路二:dp(i)代表i到字串結尾回文串的最少分割。在i到len中找到乙個j,i到j必須為回文串找出分割最少的那個即可。dp(i)=min(dp(j+1)+1)i<=j10.正規表示式匹配(自動機:動態規劃 | dfs)

'*'表示它前面的字元可以出現任意次(包含0次)

class solution 

bool dfs(char* str, char* pattern)

if(*str==*pattern||(*pattern=='.'&&*str!='\0'))

return dfs(str+1,pattern+1);

return false;}};

11.給定乙個字串,找出不含有重複字元的最長子串的長度。

思路:使用動態規劃,dp(i)代表以第i個字元為結尾的最長子串,記錄第i個字元最近一次出現的位置是否在dp(i-1)區域內

12.字串匹配

思路一:kmp演算法,是對暴力演算法回溯的一種改進(不需要進行回溯,直接從原位進行匹配),並且新增引進了已經匹配字串的最長公共字首和字尾的概念(字首和字尾相同模式串可以移位),讓下一次從模式串開始匹配的位置盡可能大。

13.把乙個0-1串(只包含0和1的串)進行排序,你可以交換任意兩個位置,問最少交換的次數?

思路:最左邊的那些

0和最右邊的那些

1都可以不管;乙個指標p1指向0的下乙個字元和乙個遍歷指標

14.字串的最長公共子串和最長公共子串行

公共子串

思路:都可以使用dp(i,j)來處理,代表s1以i結尾和s2以j結尾的最長公共子串;

公共子串行

思路:dp(i,j)代表s1在i和s2在j的最長公共子串行;字元相等(+1)字元不等(以每乙個字串為結尾取最大)

15.大數相加

思路:兩個字串進行相加,在返回字串即可;處理好進製問題即可。

擴充套件:大數相乘

思路:按位相乘得到的結果,存起來,轉化為大數相加問題

擴充套件:列印從 1 到最大的 n 位數

思路:每次確定一位,每次都確定為0~9直到位數夠,進行列印即可。

演算法之查詢題型總結

1.有序陣列的查詢 二分法 每次迴圈找middle元素與查詢元素比較,確定元素在左半邊還是在右半邊。要注意程式設計的準確性,ringht n 1,while的判斷條件就為left right,而且更新right時right middle 1,left middle 1。2.行列遞增矩陣的查詢 從右上...

字串 演算法總結

1.字串的複製 char scopy char str1,const char str2 int main char scopy char str1,const char str2 str1 j 0 return str1 2.字串的回文 判斷字串是否是回文 include include usin...

字串演算法總結

易犯錯誤 1 a c a 輸入的是大寫 a c減成了小寫 a 導致陣列的下標越界,程式執行時發生段錯誤 2 由字串轉換為數字時只有當字元是一位的時候才可以直接 0 如 11 就不可以直接 0 3 由數字轉化為字串時也要注意是否是一位的,如11就不可以直接用 0 轉化 4 審題不細,漏輸出,漏條件 問...