344. 反转字符串
位运算也可以实现,异或,不开空间进行交换
class Solution {public void reverseString(char[] s) {int l = 0;int r = s.length - 1;while (l < r) {s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ bs[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换l++;r--;}}}
541. 反转字符串 II
比我的解法好,因为剩下的最后部分的右指针的判断,也可以放到循环里
public String reverseStr(String s, int k) {char[] ch = s.toCharArray();for(int i = 0; i < ch.length; i += 2 * k){int start = i;//这里是判断尾数够不够k个来取决end指针的位置int end = Math.min(ch.length - 1, start + k - 1);//用异或运算反转while(start < end){ch[start] ^= ch[end];ch[end] ^= ch[start];ch[start] ^= ch[end];start++;end--;}}return new String(ch);}
剑指 Offer 05. 替换空格
常规解法
public String replaceSpace(String s) {if (s==null || s.length()==0)return s;StringBuilder sb = new StringBuilder();for (int i = 0; i < s.length(); ++i){char c = s.charAt(i);if (c == ' ') {sb.append("%20");}else{sb.append(c);}}return new String(sb);}
双指针
题目如果要求原地修改数组,空间复杂度为常数级
public String replaceSpace(String s) {if(s == null || s.length() == 0){return s;}//扩充空间,新字符串比旧字符串多 空格数量的2倍StringBuilder str = new StringBuilder();for (int i = 0; i < s.length(); i++) {if(s.charAt(i) == ' '){str.append(" ");}}//若是没有空格直接返回if(str.length() == 0){return s;}//有空格情况 定义两个指针int left = s.length() - 1;//左指针:指向原始字符串最后一个位置s += str.toString();int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置char[] chars = s.toCharArray();while(left>=0){if(chars[left] == ' '){chars[right--] = '0';chars[right--] = '2';chars[right] = '%';}else{chars[right] = chars[left];}left--;right--;}return new String(chars);}
151. 颠倒字符串中的单词
简单解法
public String reverseWords(String s) {// 除去开头和末尾的空白字符s = s.trim();// 正则匹配连续的空白字符作为分隔符分割List<String> wordList = Arrays.asList(s.split("\\s+"));Collections.reverse(wordList);return String.join(" ", wordList);}
双指针
class Solution {
/**
* 不使用Java内置方法实现
* <p>
* 1.去除首尾以及中间多余空格
* 2.反转整个字符串
* 3.反转各个单词
*/
public String reverseWords(String s) {
// System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
private StringBuilder removeSpace(String s) {
// System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
int start = 0;
int end = s.length() - 1;
while (s.charAt(start) == ' ') start++;
while (s.charAt(end) == ' ') end--;
StringBuilder sb = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
// System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
return sb;
}
/**
* 反转字符串指定区间[start, end]的字符
*/
public void reverseString(StringBuilder sb, int start, int end) {
// System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
// System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
}
private void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
剑指 Offer 58 - II. 左旋转字符串
简单解法1—直接拼串
public String reverseLeftWords(String s, int n) {
return s.substring(n) + s.substring(0, n);
}
简单解法2—取余
public String reverseLeftWords(String s, int n) {
s += s;
return s.substring(n, s.length()/2);
}
三次反转
class Solution {
public String reverseLeftWords(String s, int n) {
int len=s.length();
StringBuilder sb=new StringBuilder(s);
reverseString(sb,0,n-1);
reverseString(sb,n,len-1);
return sb.reverse().toString();
}
public void reverseString(StringBuilder sb, int start, int end) {
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
}
