求字串中的,最長不重複子串--java程式碼
阿新 • • 發佈:2019-02-08
package ali; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.TreeMap; public class Main { public static void main(String[] args) { String str1 = "hellowdhelloko"; max_unique_substring3(str1); } //O(N^2)的時間複雜度 static void max_unique(String str) { // begin用來儲存 最長不重複子串的 開始索引 int begin=0; // maxlen用來儲存最長不重複子串的 長度 int maxlen = 0; // 定義一個容器,用來儲存遍歷時候遇到的每一個字元的出現次數情況 TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>(); int n = str.length(); int j=0; for(int i=0; i<n; ++i) { // 初始化 hash 這個陣列,用0補充 for(int k=0; k<n; k++) { tm.put(str.charAt(k), 0); } tm.put(str.charAt(i), 1); // 往i+1開始往後找,遇到和i索引處不一樣的元素,就將那個位置的“鍵值”置1; // 遇到一樣的就 break,讓j停在現在這個位置 for(j=i+1; j<n; ++j) { if(tm.get(str.charAt(j)) == 0) tm.put(str.charAt(j), 1); else break; } // 上面j剛好停在了,第一次出現重複的那個位置,相減即為這個時候的最長子串長度, // i索引是其的開始 if(j-i > maxlen) { maxlen = j-i; begin = i; } } System.out.println(maxlen + " " + str.substring(begin, begin+maxlen)) ; } //O(N)的時間複雜度 static void max_unique_substring3(String str) { int maxlen = 0; int begin = 0; int n = str.length(); int[] next = new int[n]; //next[i]記錄了下一個與str[i]重複的字元的位置 int[] first = new int[n+1]; //first[i]記錄str[i]後面最近的一個重複點 TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>(); // 初始化 tm 這個陣列,用0補充 for(int k=0; k<n; k++) { tm.put(str.charAt(k), n); } first[n] = n; for(int i=n-1; i>=0; i--) { // next[i]記錄了下一個與str[i]重複的字元的位置 first[i]記錄str[i]後面最近的一個重複點 // tm中存放的就是 下一個與str[i]重複的字元的位置 , next[i] = tm.get(str.charAt(i)); // 在這會進行 更新 tm tm.put(str.charAt(i),i); // 如果next存放的這個 索引 小於 str[i]後面最近的 1 個重複點。如果無,就是 n 這個數字 if (next[i] < first[i+1]) first[i] = next[i]; else first[i] = first[i+1]; //生成first[]表,複雜度是O(N)的 } for(int i=0; i<n; i++) { if (first[i]-i > maxlen) { maxlen = first[i]-i; begin = i; } } System.out.println(maxlen + " " + str.substring(begin, begin+maxlen)); } }