①、反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
力扣(LeetCode)链接:https://leetcode.cn/problems/reverse-string
事例: 输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]
思路:
利用双指针left和right分别指向头和尾,交换left和right的值,交换后left向前进,right向后进,当left遇上或超过right的时候,字符串反转完成。整个过程都是关于字符串中点对称交换的,故交换完就是反转后的字符串。
代码:
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while(left < right){
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
②、反转字符串Ⅱ
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
力扣(LeetCode)链接:https://leetcode.cn/problems/reverse-string-ii
事例:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
思路:
遍历字符串,变量i记作当前索引值,当后续字符串长度大于k时,直接反转i + k的字串,随后i += 2k。当遍历结束后,获得的字符串即是部分反转的字符串。
代码:
public String reverseStr(String s, int k) {
if(s == null || s.equals("")) return s;
char[] help = s.toCharArray();
for(int i = 0;i < help.length;i += k * 2){
int left = i;
int right = Math.min(i + k - 1,help.length - 1);
while(left < right){
char c = help[left];
help[left] = help[right];
help[right] = c;
left++;
right--;
}
}
return new String(help);
}
③、替换空格
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
力扣(LeetCode)链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof
事例:
输入:s = "We are happy."
输出:"We%20are%20happy."
思路:
创建一个StringBuilder存放结果,使用append方便字符串的拼接。当遇到空格时,append(%20),其余照常拼接即可。
代码:
public String replaceSpace(String s) {
if(s == null || s == "") return s;
char[] arr = s.toCharArray();
StringBuilder sb = new StringBuilder();
for(int i = 0;i < arr.length;i++){
char c = arr[i];
if(c != ' '){
sb.append(c);
}else{
sb.append("%20");
}
}
return sb.toString();
}
④、反转字符串中的单词
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
力扣(LeetCode)链接:https://leetcode.cn/problems/reverse-words-in-a-string
输入:s = "the sky is blue"
输出:s = "blue is sky the"
思路:
①、由于字符串中的空格是随机出现的,故需要对字符串中的空格进行去重处理,即除去头尾和中间连续的空格。然后将整个字符串进行反转,此时字符串中所有单词顺序都逆转,不过每个单词也被逆转,最后再遍历字符串,反转每个单词。
代码:
public String reverseWords(String s){
if(s == null || s == "") return s;
StringBuilder sb = new StringBuilder();
sb = removeSpace(s);
reverse(sb,0,sb.length() - 1);
reverseEachWords(sb);
return sb.toString();
}
public StringBuilder removeSpace(String s){
//去头去尾
StringBuilder sb = new StringBuilder();
char[] arr = s.toCharArray();
int left = 0;
int right = arr.length - 1;
while(left < right && arr[left] == ' ') left++;
while(left < right && arr[right] == ' ') right--;
for(int i = left;i <= right;i++){
char c = arr[i];
if(c != ' ' || sb.charAt(sb.length() - 1) != ' '){
sb.append(c);
}
}
return sb;
}
public void reverse(StringBuilder s,int left,int right){
while(left < right){
char temp = s.charAt(left);
s.setCharAt(left, s.charAt(right));
s.setCharAt(right, temp);
left++;
right--;
}
}
public void reverseEachWords(StringBuilder s){
int start = 0;
int end = start + 1;
int n = s.length();
while(start < n){
while(end < n && s.charAt(end) != ' ') end++;
reverse(s,start,end - 1);
start = end + 1;
end = start + 1;
}
}
②、借助栈实现单词的逆序,创建一个StringBuilder变量tmp,记录每个单词,当遇到空格且tmp中有单词时,则将单词压入栈,遍历结束后,将栈中的单词依次弹出就可获得结果。
代码:
public String reverseWords(String s){
if(s == null || s == "") return s;
//找出单词 将单词放入栈中
Stack<String> stack = new Stack<>();
char[] arr = s.toCharArray();
StringBuilder tmp = new StringBuilder(); //临时变量 存储单词
for(int i = 0;i < arr.length;i++){
char c = arr[i];
if(c != ' '){
tmp.append(c);
}else{
if(tmp.length() > 0){
stack.push(tmp.toString());
tmp = new StringBuilder();
}
}
}
if(tmp.length() > 0) stack.push(tmp.toString());
StringBuilder res = new StringBuilder();
int n = stack.size();
for(int i = 0;i < n - 1;i++){
res.append(stack.pop());
res.append(" ");
}
res.append(stack.pop());
return res.toString();
}
⑤、左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
力扣(LeetCode)链接:https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof
事例
输入: s = "abcdefg", k = 2 输出: "cdefgab"
思路:
当k值等于s长度的倍数时,左旋转k值也就是s本身,故先将k转化成k % s,左旋的操作可以分成逆转[0,k)和[k,s.length),最终逆转整个字符串。
以上述事例为例,[0,k)和[k,s.length)这两段都逆转了两次,故a-b和c-g这两子串内部的字符相对次序不变,而整个字符串只逆转了一次,故两子串之间的次序逆转了。最终形成左旋转。
代码:
public String reverseLeftWords(String s, int n) {
if(s == null || s == "") return s;
n = n % s.length();
s = reverse(s,0,n - 1);
s = reverse(s,0,s.length() - 1);
s = reverse(s,0,s.length() - 1 - n);
return s;
}
public String reverse(String s,int left,int right){
char[] arr = s.toCharArray();
while(left < right){
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
return new String(arr);
}