String 內置類型,不可理性,要更改的話考慮轉StringBuffer,StringBuilder,char[]之類java
對java來講,一個char的範圍 [0,65535],16位面試
和數組相關,內容普遍正則表達式
概念理解:字典序,哪一個排在字典前面,哪一個字典序就小數組
簡單操做: 插入、刪除字符,旋轉ui
規則判斷 羅馬數字轉換,是不是合法的整數、浮點數spa
數字運算(套數加法、二進制加法)code
排序、交換(partition過程)排序
字符計數(hash): 變位詞遞歸
匹配(正則表達式、全串匹配、KMP、週期判斷)ci
動態規劃(LCS、編輯距離、最長迴文子串)
搜索(單詞變換、排列組合)
思路:快排partition 最左邊0和最右邊的1均可以無論
public int exchangeTimes(String s){ int answer = 0; for(int i = 0, j = s.length() - 1; i < j; i++, j--){ for(; i < j && s.charAt(i) == '0'; i++); for(; i < j && s.charAt(j) == '1'; j--); if(i < j) answer++; } return answer; }
public void solve(char[] chars){ //先刪除a,能夠利用原來字符串的空間,過程相似插入排序 int n = 0;//刪除a後的字符數組長度 int bCount = 0; for(int i = 0; s[i] != '\0'; i++){ if(chars[i] == 'a'){ chars[n++] = chars[i]; } if(chars[i] == 'b'){ bCount++; } } //從後往前複製 //步驟1. 遍歷計算新串長度,b出現的次數2. 從後往前遍歷 3.舊串複製,若是遇到b,複製兩遍 int newLength = n + bCount; chars[newLength] = '\0'; for(int i = n, j = newLength - 1; i >= 0; i--){ chars[j--] = chars[i]; if(chars[i] == 'b'){ chars[j--] = 'b'; } }
public void replaceSpace(char[] chars){ int length = 0; int spaceCount = 0; for(int i = 0; chars[i] != '\0'; i++){ length++; if(chars[i] == ' '){ spaceCount++; } } int newLength = length + 2 * spaceCount; chars[newLength] = '\0'; for(int i = newLength - 1, j = length; j >= 0; j--){ if(chars[j] == ' '){ char[i] = '0'; char[--i] = '2'; char[--i] = '%'; }else{ char[i--] = char[j]; } } }
方法1 快排partition,由於過程不穩定,因此數字相對順序會變化
public void sortStar(char[] chars){ for(int i = 0 , j = 0; j < a.length; j++){ if(chars[i] == '*'){ swap(a[i++], a[j]) } } } private void swap(char[] chars, int i, int j){ char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; }
方法2 倒着處理
public void sortStar(char[] chars){ int length = chars.length; int i = length - 1; for(int j = length - 1; j >= 0; j--){ if(chars[j] != '*'){ chars[i--] = chars[j]; } } while(i >= 0){ chars[i--] = '*'; } }
注意:以上兩種解法的異同,方法1,用到交換和快排partition思想,可是沒法保證數字的順序;方法2,使用倒着向前處理的思想,若是必須用交換,只能採用方法1
翻轉句子中所有的單詞,單詞內容不變,例如I'm a student. 變爲student. a I'm 思路:in-place翻轉 字符串第i位到第j位
while(i < j) swap(s[i++], s[j--]);
1. 翻轉整個句子:.tneduts a m'I 2. 每一個單詞單獨翻轉: students. a I'm 這段代碼寫得很是醜陋
public void revertStr(char[] chars){ int length = chars.length; //翻轉整個句子 revertInPlace(chars, 0, length - 1); //翻轉每一個單詞 String str = new String(chars); String[] strs = str.split(" "); int wordCounts = strs.length; int[] eachLength = new int[wordCounts]; int i = 0; for(String s : strs){ eachLength[i++] = s.length(); } int start = 0; for(int j = 0; j < wordCounts; j++){ revertInPlace(chars, start, start + eachLength[j] - 1); start += eachLength[j] + 1; } } private void revertInPlace(char[] chars, int i, int j){ while(i < j){ swap(chars, i++, j--); } } private void swap(char[] chars, int i, int j){ char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; }
abcd 移動1次爲bcda,移動兩次爲cdab,移動三次爲dabc 結論:長度爲n,移動m次,至關於移動m%n次 - 前m%n位翻轉,後n-m%n位翻轉 - 整體再翻轉一次
public void circularMove(char[] chars, int m){ int n = chars.length; revertInPlace(chars, 0, m % n - 1); revertInPlace(chars, m % n, n - 1); revertInPlace(chars, 0, n - 1); } private void revertInPlace(char[] chars, int i, int j){ while(i < j){ swap(chars, i++, j--); } } private void swap(char[] chars, int i, int j){ char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; }
in-place(原地)理解
自己爲O(1)空間
遞歸,堆棧空間能夠不考慮
原地相關的問題
字符串循環左移、右移
快排partition相關
滑動窗口
能達到O(n)的時間複雜度
O(1)的空間複雜度
規則相關---細緻
匹配(暴力):KMP比較少見
Manacher----要求比較高的筆試