344.翻转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"] 输出:["h","a","n","n","a","H"]
思路
这题要注意到题目说的“原地”,这就表明我们不能开辟其他的空间,那么如果我们需要实现反转,我们只能做的就是交换,构造两个指针,分别指向第一个元素和最后一个元素,一开始最后的和最前的元素进行交换,直至两指针重叠为结束。
代码
class Solution {
public void reverseString(char[] s) {
int len = s.length;
int i = 0,j = len-1;
while(i<j){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
}
}
卡码网:54.替换数字
题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
输入
输入一个字符串 s,s 仅包含小写字母和数字字符。
输出描述
打印一个新的字符串,其中每个数字字符都被替换为了number
输入示例
a1b2c3
输出示例
anumberbnumbercnumber
思路
我可以重新构造一个数组,然后遇到小写字母就放原来的,遇到数字就放单词,我遇到的一个比较卡的点是我对String变成数组不太了解,本质就是对Java的常用方法不太了解
代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] sin = s.toCharArray();
int count = 0;
for(int i = 0;i<sin.length;i++){
if(sin[i]>'0'&&sin[i]<='9'){
count++;
}
}
int size = sin.length + count*5;
char[] res = new char[size];
int j = 0;
for(int i = 0;i<sin.length;i++){
if(sin[i]>'0'&&sin[i]<='9'){
res[j++] = 'n';
res[j++] = 'u';
res[j++] = 'm';
res[j++] = 'b';
res[j++] = 'e';
res[j++] = 'r';
}else{
res[j++] = sin[i];
}
}
String ans = new String(res);
System.out.print(ans);
}
}
151.反转字符串中的单词
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue
" 输出:"blue is sky the
"
示例 2:
输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。
思路
这题一开始没有想出来,我是想着先用trim函数把前面和后面的空格都去掉,然后再从后面开始遍历,构造一个新的string,把最后面的单词依次放入这个string,但是可以知道的是这样子做时间复杂度是o(n2),空间复杂度是o(n)
参考了一下标准的想法,把复杂度降到了o(n),空间复杂度为o(n):
先去除前后的空格,以及单词之间多余的空格,然后再将整个字符串进行逆置,最后将单词进行逆置。这个做法很妙。
我的代码现在还有问题,如果有朋友发现我的问题可以私信我修改,感谢!
代码
class Solution {
public String reverseWords(String s) {
//去除多余空格
StringBuilder str = removeSpace(s);
//反转整个句子
reverseAll(str,0,str.length()-1);
//反转每一次单词
reverseWords(str);
String string = str.toString();
return string;
}
public StringBuilder removeSpace(String s){
//如果当前的字符是空格,最后一位不是空格,可以加空格,如果是字符就直接加上去
StringBuilder str = new StringBuilder();
int start = 0,end = s.length()-1;
while(s.charAt(start)==' ')start++;
while(s.charAt(end)==' ')end--;
for(int i = start;i<=end;i++){
char c = s.charAt(i);
if(c != ' '||str.charAt(str.length()-1)!=' '){
str.append(c);
}
}
return str;
}
public void reverseAll(StringBuilder str,int start,int end){
while(start<end){
char c = str.charAt(start);
str.setCharAt(start,str.charAt(end));
str.setCharAt(end,c);
start++;
end--;
}
}
public void reverseWords(StringBuilder str){
int start = 0,end = 1;
int n = str.length();
while(start<n){
while(str.charAt(end)!=' '&&end<n){
end++;
}
reverseAll(str,start,end-1);
start = end+1;
end = start+1;
}
}
}
卡码网 55.右旋字符串
题目描述
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
输入描述
输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出描述
输出共一行,为进行了右旋转操作后的字符串。
输入示例
2
abcdefg
输出示例
fgabcde
提示信息
数据范围:
1 <= k < 10000
思路
这题的思路和前面的一题如出一辙,之前做过这一种题目,也对这种题目比较印象深刻,可以总结一下就是运用两次翻转,可以把两个部分的字符窜进行位置的互换。
代码
import java.util.*;
class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
scan.nextLine();
String str = scan.nextLine();
StringBuilder sb = new StringBuilder(str);
reverseString(sb,0,sb.length()-1);
reverseString(sb,0,num-1);
reverseString(sb,num,sb.length()-1);
System.out.print(sb.toString());
}
public static void reverseString(StringBuilder sb,int start,int end){
while(start<end){
char c = sb.charAt(start);
sb.setCharAt(start,sb.charAt(end));
sb.setCharAt(end,c);
start++;
end--;
}
}
}