找到字串的最長無重複字元子串 & 字串的統計字串
找到字串的最長無重複字元子串
《程式設計師程式碼面試指南》第94題 P300 難度:尉★★☆☆
首先是幾個變數的介紹:雜湊表map,key表示某個字元,value為這個字元最近一次出現的位置。整型變數pre,如果當前遍歷到字元str[i],pre表示在必須以str[i-1]字元結尾的情況下,最長無重複字元子串開始位置的前一個位置,初始時pre=-1。整型變數len,記錄以每一個字元結尾的情況下,最長無重複字元子串長度的最大值,初始時,len=0。從左到右依次遍歷str,假設現在遍歷到str[i],接下來求在必須以str結尾的情況下,最長無重複字元子串的長度。
map(str[i])
根據pre的定義,pre+1表示在必須以str[i-1]字元結尾的情況下,最長無重複字元子串的開始位置。也就是說,以str[i-1]結尾的最長無重複子串是向左擴到pre位置停止的。
如果pre位置在a位置的左邊,因為str[a]不能包含進來,而str[a+1..i-1]上都是不重複的,所以以str[i]結尾的最長無重複字元子串就是str[a+1..i]。如果pre位置在a位置的右邊,以str[i-1]結尾的最長無重複子串是向左擴到pre位置停止
計算完長度之後,pre位置和a位置哪一個在右邊,就作為新的pre值。然後計算下一個位置的字元,整個過程中求得所有長度的最大值用len記錄下來返回即可。
具體請參看如下程式碼中的maxUnique方法。
public int maxUnique(String str) { if (str == null || str.equals("")) { return 0; } char[] chas = str.toCharArray(); int[] map = new int[256]; for (int i = 0; i < 256; i++) { map[i] = -1; } int len = 0; int pre = -1; int cur = 0; for (int i = 0; i != chas.length; i++) { pre = Math.max(pre, map[chas[i]]); cur = i - pre; len = Math.max(len, cur); map[chas[i]] = i; } return len; }
字串的統計字串
題目:字串的統計字串
《程式設計師程式碼面試指南》第80題 P258 難度:士★☆☆☆
這題沒什麼含金量,逐個遍歷,str[i]==str[i-1]就num++,否則拼接字串。注意在遍歷完成後還需要再拼接上最後一種字元的次數。不多說,直接看程式碼:
public String getCountString(String str) {
if (str == null || str.equals("")) {
return "";
}
char[] chs = str.toCharArray();
String res = String.valueOf(chs[0]);
int num = 1;
for (int i = 1; i < chs.length; i++) {
if (chs[i] != chs[i - 1]) {
res = concat(res, String.valueOf(num), String.valueOf(chs[i]));
num = 1;
} else {
num++;
}
}
return concat(res, String.valueOf(num), "");
}
public String concat(String s1, String s2, String s3) {
return s1 + "_" + s2 + (s3.equals("") ? s3 : "_" + s3);
}
(個人覺得用StringBuilder效率更高一點)
進階問題:
public char getCharAt(String cstr, int index) {
if (cstr == null || cstr.equals("")) {
return 0;
}
char[] chs = cstr.toCharArray();
boolean stage = true;
char cur = 0;
int num = 0;
int sum = 0;
for (int i = 0; i != chs.length; i++) {
if (chs[i] == '_') {
stage = !stage;
} else if (stage) {
sum += num;
if (sum > index) {
return cur;
}
num = 0;
cur = chs[i];
} else {
num = num * 10 + chs[i] - '0';
}
}
return sum + num > index ? cur : 0;
}
書上的方法很繁瑣,我的方法是通過split("_")分割字串,分割後索引為奇數1、3、5…的字串通過Integer.parseInt()轉化後就是各個字元的次數,直接去統計就行,不需要像書上這樣還挨個num=num*10+chs[i]去計算次數。。