344.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1: 输入:["h","e","l","l","o"] 输出:["o","l","l","e","h"]
思路
-
题目中要求O(1)的空间,只能在原有的字符串中操作
-
将字符串转为的字符数组,定义两个首尾指针,在原字符串中交换首尾字符
public void reverseString(char[] s) {
int start = 0;
int end = s.length - 1;
while (start < end) {
//交换值
char temp = s[start];
s[start] = s[end];
s[end] = temp;
//移动指针
start++;
end--;
}
}
541. 反转字符串II
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = "abcdefg", k = 2 输出: "bacdfeg"
思路
-
根据题意可以的知道需要每2k个字符操作一次字符串,可以把字符串看成多个2k个字符组成的,分开操作
-
每一次循环的步长为2k,当步长达不到k,则直接反转剩下所有的元素
-
注意返回需要返回一个处理过的字符串,将输入的字符串以字符处理,处理完成需要将字符串数组转为新的字符串对象返回
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
//步长为2k遍历字符
for (int i = 0; i < chars.length; i+=2*k) {
//每一次2k处理字符串的起点,用于判断是否还有k字符来反转
int start = i;
//判断是否有k个,没有则取剩下的所有元素,当结束元素不足k的时候,开始的下标加上k个元素则超过了字符数组的长度
int end = Math.min(chars.length - 1,start + k - 1);
while (start < end){
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end--;
}
}
return new String(chars);
}
替换数字
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
样例输入:a1b2c3
样例输出:anumberbnumbercnumber
思路
-
遍历一遍字符串,根据字符工具类判断为数字则替换
-
java的string是不可变对象,返回结果应该重新组装一个字符串对象
public String reverseStrToNum(String s) {
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
sb.append("number");
} else {
sb.append(c);
}
}
return sb.toString();
}
151.翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1: 输入: "the sky is blue" 输出: "blue is sky the"
思路
-
移除多余空格
-
使用了char数组双指针的方法构建去除字符串前后多余的空格
-
-
将整个字符串反转
-
双指针的方法反转
-
-
将每个单词反转
举个例子,源字符串为:"the sky is blue "
-
移除多余空格(前后的空格) : "the sky is blue"
-
整体字符串反转:"eulb si yks eht"
-
单词反转根据单词间空格反转:"blue is sky the"058
class Solution {
public String reverseWords(String s) {
char[] chars = s.toCharArray();
//1.去除首尾以及中间多余空格
chars = removeExtraSpaces(chars);
//2.整个字符串反转
reverse(chars, 0, chars.length - 1);
//3.单词反转
reverseEachWord(chars);
return new String(chars);
}
private void reverseEachWord(char[] chars) {
//每一个单词的开始
int start = 0;
for (int i = 0; i <= chars.length; i++) {
//当指向空格或者末尾开始反转
if ( i == chars.length || chars[i] == ' '){
reverse(chars,start,i-1);
start = i + 1;
}
}
}
private void reverse(char[] chars, int i, int i1) {
//定义两个指针
while (i < i1){
char temp = chars[i];
chars[i] = chars[i1];
chars[i1] = temp;
i++;
i1--;
}
}
private char[] removeExtraSpaces(char[] chars) {
//定义慢指针
int slow = 0;
//遍历快指针
for (int fast = 0; fast < chars.length; fast++) {
//当快指针的元素不为空格时,开始覆盖慢指针所在的元素,即将不为空的元素向前覆盖,覆盖所有空格
if (chars[fast] != ' ') {
//单词和单词直线需要加空格
if (slow != 0){
chars[slow++] = ' ';
}
//通过快慢指针开始覆盖
//fast 遇到空格或遍历到字符串末尾,就证明遍历完一个单词了
//slow就是最后一个单词的最后字母的下标
while (fast < chars.length && chars[fast] != ' '){
chars[slow++] = chars[fast++];
}
}
}
//构建新的数组
char[] ints = new char[slow];
System.arraycopy(chars,0,ints,0,ints.length);
return ints;
}
}
右旋字符串
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
思路
-
将整个字符串全部反转abcdefg->gfedcba
-
反转0到目标值的字符gfedcba->fgedcba
-
反转剩下的字符
public static void reverse(String str,int num) {
char[] chars = str.toCharArray();
//反转整个字符串
reverseString(chars,0,chars.length);
//反转前一段字符串,此时的字符串首尾尾是0,n - 1
reverseString(chars,0,num - 1);
//反转后一段字符串,此时的字符串首尾尾是n,len - 1
reverseString(chars,num,chars.length -1);
}
public static void reverseString(char[] ch, int start, int end) {
while (start < end) {
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
start++;
end--;
}
}