找出字串中的最長連續數字子串
阿新 • • 發佈:2019-01-25
題目
給出一個字串作為輸入,找出其中最長的連續數字串並返回其長度和起始index。如果存在長度相同的連續數字串,返回最後一個連續數字串。如果沒有,返回0和0。
Analysis
對於這道題目,首先我們需要進一步縮小題目範圍。題目中並沒有給出字串中的數字都是什麼數字。比如是否包含負數,是否包含小數等。因此簡單起見,我們假設該輸入字串中只包含正整數。且假設輸入字串中沒有空格。
設輸入字串的長度為n
。
從Best Conceivable Time的角度考慮,這道題的時間複雜度至少為O(n)
。也就是說,對於這道題而言,我們至少需要遍歷整個輸入的字串一次才能得出答案。因此在時間複雜度角度考慮,我們並沒有多少優化的空間。
從空間複雜度的角度考慮,brute-force解法比較直觀,就是遍歷一遍整個輸入字串,找出並記錄其中所有的連續數字子串。然後在所有被記錄的數字子串中找出最長的那個。因為題目要求有多個最長子串時返回最後一個,所以我們只需要返回最後一個被記錄的最長子串即可。這個方法最壞情況下需要記錄整個輸入字串。所以空間複雜度為O(n)
。
具體實現如下:
public class LongestNumberSubstring {
public static int[] findLongestNumSubstring(String input) {
// If the string is empty, return [0, 0] directly.
if (input == null || input.length() == 0) {
return new int[]{0, 0};
}
int index = 0;
int[] ret = new int[]{0, 0}; //[start_index, length]
while (index < input.length()) {
StringBuilder sb = new StringBuilder();
while (index < input.length() && Character.isDigit(input.charAt(index))) {
sb.append(input.charAt(index));
index++;
}
// If current substring is not empty and is longer than or equal to the previously found substring
// Put it in return values.
if (sb.length() != 0 && ret[1] <= sb.length()) {
ret[1] = sb.length();
ret[0] = index - sb.length();
}
index++;
}
return ret;
}
優化
但事實上,考慮到我們需要的只是子字串的起始index和長度,這道題可以用2 pointers的方法解決。並不需要記錄中間產生的任何子字串。這樣的話我們可以將演算法的空間複雜度降到O(1)
。
具體演算法為:從頭到尾遍歷字串,每當遇到數字連續數字子串時,記錄其長度。並與全域性記錄的最長長度相比較。如果更長的話,就記錄當前長度和開始index。
實現如下:
public class LongestNumberSubstring {
public static int[] findLongestNumSubstring(String input) {
// If the string is empty, return [0, 0] directly.
if (input == null || input.length() == 0) {
return new int[]{0, 0};
}
int index = 0;
int[] ret = new int[]{0, 0}; //[start_index, length]
int currLen = 0;
while (index < input.length()) {
currLen = 0;
while (index < input.length() && Character.isDigit(input.charAt(index))) {
currLen++;
index++;
}
// If current substring is longer than or equal to the previously found substring
// Put it in return values.
if (currLen != 0 && ret[1] <= currLen) {
ret[1] = currLen;
ret[0] = index - currLen;
}
index++;
}
return ret;
}
}