给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc"
输出: "s'teL ekat edoCteeL tsetnoc"
注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii
题目分析:这个题最先想到的StringBuilder的reverse()方法,双指针找到每个单词,用一个小的StringBuilder翻转,再连接到一个大的StringBuilder里面。
还可以用String的split()按空格分割成String[] (空格也会保存在String数组中,变成[Let's, take, LeetCode, contest]),搭配trim(),想办法翻转就可以。
其中有种比较独特的异或交换法,可对整数和字符进行交换:
三次异或,交换a,b:
a = a ^ b; // 把a,b二进制不同的位置记录为1,保存在a中
b = a ^ b; // 与1^,相当于取反,在b中把两数不同的位置取反,则把b变成了原来的a值
a = a ^ b; //此时b是原来的a值,同样在a值中把两数不同的位置取反,则把a变成了原来的b值
(如果是字符,java中需要强转,因为异或把它们变成了整型)
1 //异或交换法,交换两个整数或者是字符(当成整数处理了),可以用异或代替tmp 2 //题目说不会有额外的空格,说明最后结束的一定不是空格 3 class Solution { 4 public String reverseWords(String s) { 5 if(s == null || s.length() == 0) return s; 6 char[] tmp = s.toCharArray(); 7 int slow = 0; 8 int fast = 0; 9 while(fast < tmp.length){ 10 if(tmp[fast] == ' '){ 11 reverseWord(tmp,slow,fast-1); 12 slow = fast+1; 13 } 14 fast++; 15 } 16 reverseWord(tmp,slow,tmp.length-1);//由于题目规定,最后一定不含有空格,所以最后一组单独处理 17 return new String(tmp); 18 } 19 //把一个功能剥离出来,写成函数真的很清爽 20 public char[] reverseWord(char[] s,int start,int end){ 21 while(start < end){ 22 s[start] = (char)(s[start] ^ s[end]); //记录两数二进制相异的位,相异的位为1 23 s[end] = (char)(s[start] ^ s[end]); //与1^相当于取反,将s[end]中与s[start]中不同的位取反,s[end]变成了s[start] 24 s[start] = (char)(s[start] ^ s[end]);//s[end]是原来s[start]的值,s[start]记录两数相异的位,所以s[start]变成了s[end] 25 start++; 26 end--; 27 } 28 return s; 29 } 30 }