題目: 替換空格
請實現一個函數,吧字符串中的每個空格替換成 “%20”。例如輸入 “We are happy.” , 這輸出“We%20arehappy.”。(不使用replace&insert方法和必須在原串中改變)
解題思路:
解法1:
思路: 複雜度O(n²),遍歷所有字符並添加後移動後面的字符串(不推薦)。
如字符串“We are happy.”:
初始化:
W | e | a | r | e | h | a | p | p | y | . |
第一次移動(陰影代表需要移動的字符):
W | e | % | 2 | 0 | a | r | e | h | a | p | p | y | . |
第二次移動(深色配筋說明需要移動兩次):
W | e | % | 2 | 0 | a | r | e | % | 2 | 0 | h | a | p | p | y | . |
由此思路可知時間複雜度O(n²),可寫出代碼:
// 複雜度O(n²),遍歷所有字符並在添加後空格後面的字符串向後移動(不推薦)
public static StringBuilder replace1(StringBuilder target) {
if (target == null) {
return null;
}
for (int i = 0; i < target.length(); i++) {
if (target.charAt(i) == ' ') {
StringBuilder template = new StringBuilder(target);
//改變原來String的長度,增加2
target.setLength(target.length() + 2);
target.setCharAt(i, '%');
target.setCharAt(i + 1, '2');
target.setCharAt(i + 2, '0');
for (int j = i + 3; j < target.length(); j++) {
target.setCharAt(j, template.charAt(j - 2));
}
i += 2;
}
}
return target;
}
解法2:
思路:既然我們需要替換空格,那我們可不可以先對空格進行計數,然後拓展數組大小,再從後向前進行賦值呢?
W | e | a | r | e | h | a | p | p | y | . |
由字符串可知空格有2個,故需拓展4個大小,p1,p2分別爲原來和拓展後的最後一個字符的位置:
W | e | a | r | e | h | a | p | p | y | . | ||||||
p1 | p2 |
將p1的下標的值賦給p2:
W | e | a | r | e | h | a | p | p | h | a | p | p | y | . | ||
p1 | p2 |
若是空格則賦 %20三個字符:
W | e | a | r | e | h | % | 2 | 0 | h | a | p | p | y | . | ||
p1 | p2 |
則到終點爲:
W | e | % | 2 | 0 | a | r | e | % | 2 | 0 | h | a | p | p | y | . |
p1. p2 |
故可寫出代碼:
// 複雜度O(n),先記錄空格個數在進行替換移動。
public static StringBuilder replace2(StringBuilder target) {
if (target == null) {
return null;
}
// 記錄空格個數
int spaceNum = 0;
for (int i = 0; i < target.length(); i++) {
if (target.charAt(i) == ' ') {
spaceNum++;
}
}
// 以前下標
int oldIndex = target.length() - 1;
// 新的長度
int newLength = target.length() + spaceNum * 2;
// 新下標
int newIndex = newLength - 1;
target.setLength(newLength);
// 這裏注意:
// 1.循環是從後往前,這樣可以避免重複移動
// 2.判斷條件:oldIndex < newIndex && newIndex >= 0 則無需全部遍歷,若oldIndex<newIndex則代表所有空格已經被替換
for (; oldIndex < newIndex && newIndex >= 0; oldIndex--) {
if (target.charAt(oldIndex) == ' ') {
// 這裏由於是從後向前循環,所以插入字符也應該倒插
target.setCharAt(newIndex--, '0');
target.setCharAt(newIndex--, '2');
target.setCharAt(newIndex--, '%');
} else {
target.setCharAt(newIndex--, target.charAt(oldIndex));
}
}
return target;
}
完整代碼如下:
package problem4;
/**
* 題目: 替換空格
* 請實現一個函數,吧字符串中的每個空格替換成 “%20”。例如輸入 “We are happy.” , 這輸出“We%20arehappy.”。(不使用replace&insert方法和必須在原串中改變)
* Created by fengyuwusong on 2018/1/16 14:57.
*/
public class ReplaceSpance {
// 複雜度O(n²),遍歷所有字符並添加後移動(不推薦)
public static StringBuilder replace1(StringBuilder target) {
if (target == null) {
return null;
}
for (int i = 0; i < target.length(); i++) {
if (target.charAt(i) == ' ') {
StringBuilder template = new StringBuilder(target);
//改變原來String的長度,增加2
target.setLength(target.length() + 2);
target.setCharAt(i, '%');
target.setCharAt(i + 1, '2');
target.setCharAt(i + 2, '0');
for (int j = i + 3; j < target.length(); j++) {
target.setCharAt(j, template.charAt(j - 2));
}
i += 2;
}
}
return target;
}
// 複雜度O(n),先記錄空格個數在進行替換移動。
public static StringBuilder replace2(StringBuilder target) {
if (target == null) {
return null;
}
// 記錄空格個數
int spaceNum = 0;
for (int i = 0; i < target.length(); i++) {
if (target.charAt(i) == ' ') {
spaceNum++;
}
}
// 以前下標
int oldIndex = target.length() - 1;
// 新的長度
int newLength = target.length() + spaceNum * 2;
// 新下標
int newIndex = newLength - 1;
target.setLength(newLength);
// 這裏注意:
// 1.循環是從後往前,這樣可以避免重複移動
// 2.判斷條件:oldIndex < newIndex && newIndex >= 0 則無需全部遍歷,若oldIndex<newIndex則代表所有空格已經被替換
for (; oldIndex < newIndex && newIndex >= 0; oldIndex--) {
if (target.charAt(oldIndex) == ' ') {
// 這裏由於是從後向前循環,所以插入字符也應該倒插
target.setCharAt(newIndex--, '0');
target.setCharAt(newIndex--, '2');
target.setCharAt(newIndex--, '%');
} else {
target.setCharAt(newIndex--, target.charAt(oldIndex));
}
}
return target;
}
public static void main(String[] args) {
// 編寫測試用例
// 第一個方法
// 開頭空
System.out.println(replace1(new StringBuilder(" 2354")));
// 結尾空
System.out.println(replace1(new StringBuilder("2345 ")));
// 中間空
System.out.println(replace1(new StringBuilder("23 56")));
// 全部情況一起
System.out.println(replace1(new StringBuilder(" 2 34 ")));
// 空
System.out.println(replace1(null));
System.out.println(replace1(new StringBuilder("")));
// 單獨空格
System.out.println(replace1(new StringBuilder(" ")));
// 連續空格
System.out.println(replace1(new StringBuilder(" ")));
System.out.println("----------------------");
// 第二個
// 開頭空
System.out.println(replace2(new StringBuilder(" 2354")));
// 結尾空
System.out.println(replace2(new StringBuilder("2345 ")));
// 中間空
System.out.println(replace2(new StringBuilder("23 56")));
// 全部情況一起
System.out.println(replace2(new StringBuilder(" 2 34 ")));
// 空
System.out.println(replace2(null));
System.out.println(replace2(new StringBuilder("")));
// 單獨空格
System.out.println(replace2(new StringBuilder(" ")));
// 連續空格
System.out.println(replace2(new StringBuilder(" ")));
}
}
相關問題:
有兩個排序的數組A1和A2,內存在A1的末尾有足夠的空餘空間容納A2。
請事先一個函數,把A2中的所有數字插入到A1中並且所有的數字是排序的。
解題思路:
解題思路:從尾到頭比較A1和A2中的數字,並把較大的數字複製到A1的合適位置。
代碼:
package problem4;
/**
* 相關問題:
* 有兩個排序的數組A1和A2,內存在A1的末尾有足夠的空餘空間容納A2。
* 請事先一個函數,把A2中的所有數字插入到A1中並且所有的數字是排序的。
* Created by fengyuwusong on 2018/1/16 23:00.
*/
public class Relative {
//解題思路:從尾到頭比較A1和A2中的數字,並把較大的數字複製到A1的合適位置。
public static int[] merge(int[] a1, int[] a2, int a1Length, int a2Length) {
// a1的下標
int a1Index = a1Length - 1;
// a1的下標
int a2Index = a2Length - 1;
// 合併後總下標
int mergeIndex = a1Length + a2Length - 1;
// 判斷長度是否足夠
if (a1.length < mergeIndex + 1) {
System.out.println("a1長度不夠");
return null;
}
// 進行從後向前循環比較並替換 優勢:不用移動前面的數字
while (a1Index >= 0 && a2Index >= 0) {
if (a1[a1Index] >= a2[a2Index]) {
a1[mergeIndex] = a1[a1Index];
a1Index--;
mergeIndex--;
} else {
a1[mergeIndex] = a2[a2Index];
a2Index--;
mergeIndex--;
}
}
// 考慮情況a2比a1長度長,此時a1已經沒有數字,則將a2剩餘數字放在數組前面
// 無需考慮a1情況,因爲a2本身已經在數組a1中
while (a2Index >= 0) {
a1[mergeIndex] = a2[a2Index];
a2Index--;
mergeIndex--;
}
return a1;
}
public static void show(int[] a1) {
if (a1 == null) {
return;
}
for (int i = 0; i < a1.length; i++) {
System.out.print(a1[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] a1 = {1, 3, 6, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int[] a2 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// a2比a1長
a1 = merge(a1, a2, 5, 9);
show(a1);
// a2比a1短
int[] a3 = {0, 1, 3, 6, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int[] a4 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
a1 = merge(a3, a4, 6, 3);
show(a1);
// a1長度不夠
int[] a5 = {1, 3, 6, 9, 10};
int[] a6 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
a1 = merge(a5, a6, 5, 3);
show(a1);
}
}