今天的习题与字符串有关。
1.字符串反转(力扣541)
public String reverseStr(String s, int k) { //每2k个字符翻转k个,若剩下的小于k个则全部反转。 char[] chars = s.toCharArray(); if(s.length() == 0||s.length()==1) return s; int l = 0; int index = 0; for (int i = 0; i < chars.length; i+=2*k) { //剩下的够反转 if(i+k-1 <= chars.length-1){ index = i+k-1; } //剩下的不够反转 else index = chars.length-1; l = i; while (l < index){ char temp; temp = chars[l]; chars[l] = chars[index]; chars[index] = temp; l++; index--; } } return new String(chars); }
2.替换空格(力扣剑指offer05)
采用双指针,新建一个字符数组,复制原字符数组,当遇到空格时,新建数组将其改为“%20”然后继续复制。(注意新建数组长度是原数组长度加上其中空格个数的两倍)
public String replaceSpace(String s) { if(s.length() == 0) return s; char[] chars = s.toCharArray(); int count = 0; for (int i = 0; i < chars.length; i++) { if(chars[i] == ' '){ count++; } } if(count == 0) return s; char[] chars1 = new char[chars.length+count*2]; for (int i = 0,j = 0; i < chars.length; i++) { if(chars[i] == ' '){ chars1[j] = '%'; chars1[j+1] = '2'; chars1[j+2] = '0'; j = j + 3; } else { chars1[j] = chars[i]; j++; } } return new String(chars1); }
3.反转字符串中的单词(力扣151)
从后到前遍历字符串,遇到一个单词添加到新的字符串后。也可采用先反转字符串后再反转其中的每个单词。
public String reverseWords(String s) { // String str = s.trim(); // if(str.length() == 1) // return str; // StringBuilder sb = new StringBuilder(); // int i = str.length()-1; // int j = str.length()-1; // while (i >= 0 && j >= 0){ // while (str.charAt(i) != ' ' && i > 0) i--; // if(i==0){ // sb.append(str.toCharArray(),i,j-i+1); // break; // } // else { // sb.append(str.toCharArray(),i+1,j-i); // sb.append(" "); // } // j = i; // while (str.charAt(j)==' ') j--; // i = j; // } // return sb.toString(); //去除首尾和中间的多余空格,反转字符串,反转字符串内各个单词 s = s.trim(); int start = 0; int end = s.length()-1; StringBuilder sb = new StringBuilder(); while (start <= end) { char c = s.charAt(start); if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') { sb.append(c); } start++; } for (int i = 0; i < sb.length() / 2; i++) { char temp = sb.charAt(i); sb.setCharAt(i,sb.charAt(sb.length()-1-i)); sb.setCharAt(sb.length()-1-i,temp); } int i = 0; int j = 0; while (j<sb.length()){ while (j<sb.length() && sb.charAt(j)!=' ') j++; int k = i; for (i = 0; i < (j-k)/2 ; i++) { char temp = sb.charAt(i+k); sb.setCharAt(i+k,sb.charAt(j-1-i)); sb.setCharAt(j-1-i,temp); } i = j+1; j = i+1; } return sb.toString(); }
4.左旋转字符串(力扣剑指offer58)
简单的做法需要辅助空间,原地做的话就先分别反转前n个和剩下的,再一起进行反转。
public String reverseLeftWords(String s, int n) { // StringBuilder sb = new StringBuilder(s.substring(n,s.length())); // int i = 0; // while (i<n){ // sb.append(s.charAt(i)); // i++; // } // return sb.toString(); // char[] chars = new char[s.length()]; // for (int i = n; i < s.length(); i++) { // chars[i-n] = s.charAt(i); // } // int k = s.length()-n; // int i = 0; // while (i < n){ // chars[k++] = s.charAt(i++); // } // return new String(chars); //不需要辅助空间:先反转前n个,再反转剩下的,最后一起再反转一次。 int k = n; char[] chars = s.toCharArray(); for (int i = 0; i < k/2; i++) { char temp = chars[i]; chars[i] = chars[k-1-i]; chars[k-1-i] = temp; } for (int i = k; i < (chars.length-k)/2+k; i++) { char temp = chars[i]; chars[i] = chars[chars.length-1-i+k]; chars[chars.length-1-i+k] = temp; } for (int i = 0; i < chars.length/2; i++) { char temp = chars[i]; chars[i] = chars[chars.length-1-i]; chars[chars.length-1-i] = temp; } return new String(chars); }