- 344.反转字符串
- 541. 反转字符串II
- 卡码网:54.替换数字
- 151.翻转字符串里的单词
- 卡码网:55.右旋转字符串
LeetCode344 反转字符串
题目链接:344. 反转字符串
思路:区别反转字符串和反转链表,字符串更加简单,只需要左右指针交换位置
用tmp或者异或^操作都可以互换
代码:
class Solution {
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--;
}
}
}
LeetCode541 反转字符串ii
题目链接:541.反转字符串ii
思路:
用到的函数:
● 2k(×) 2*k(√)
● s.toCharArray() 将字符串转化为字符串数组
● new String(ch) 将数组转换回字符串,return new String(chars数组)
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i=0;i<ch.length;i+=2*k){
int l = i;
int r = Math.min(ch.length-1,l+k-1);
while(l<r){
ch[l]^=ch[r];
ch[r]^=ch[l];
ch[l]^=ch[r];
l++;
r--;
}
}
return new String(ch);
}
}
卡码网54 替换数字
题目链接:54. 替换数字
思路:对于这类数组填充类的问题通常就是预先扩容,然后从后往前操作
如果想把这道题目做到极致,就不要只用额外的辅助空间了! (不过Java里的string不能修改,所以一定要使用辅助空间)
用到的函数:
● scanner的作用是读取用户输入,scanner.nextLine(),scannner.close()
● StringBuilder和String的区别在于它面向对象,字符串内容可变;但是记得输出的时候要用toString()转化成string形式,sb.append(),sb.insert(offset,xxx),sb.reverse()
● Character.isDigit(c)判断字符c是不是数字,除此之外还有isUpperCase, isLowerCase, isLetter, isWhitespace
import java.util.Scanner;
class Main{
public static void main (String[] args) {
Scanner reader = new Scanner(System.in);
String s = reader.nextLine(); //输入s
StringBuilder sb = new StringBuilder(); //创建新的可变字符串sb
for(int i = 0;i<s.length();i++){
if(Character.isDigit(s.charAt(i))){
sb.append("number");
}else{
sb.append(s.charAt(i));
}
}
System.out.println(sb);
}
}
LeetCode151 翻转字符串里的单词
题目链接:151.翻转字符串里的单词
参考学习xchar, String,StringBuilder, ArrayList怎么区别和转换
方法一:我的思路:①删除多余空格②分割字符串为数组③将数组反转
class Solution {
public String reverseWords(String s) {
StringBuilder sb =removeExtraSpaces(s);
StringBuilder sbb = new StringBuilder();
String[] words= sb.toString().split(" ");
int left = 0;
int right = words.length-1;
while(left<right){
String tmp = words[right];
words[right] = words[left];
words[left] = tmp;
left++;
right--;
}
for(String item: words){
sbb.append(item + " ");
}
sbb.deleteCharAt(sbb.length()-1);
return sbb.toString();
}
private StringBuilder removeExtraSpaces(String s){
StringBuilder sb = new StringBuilder();
int begin = 0;
int end = s.length()-1;
//首先去头去尾,char是' ',string是" "
while(s.charAt(begin)==' ') begin++;
while(s.charAt(end)==' ') end--;
while(begin<=end){ //这里是<=因为begin可以递增到最后一位
if(s.charAt(begin)!=' '|| sb.charAt(sb.length()-1)!=' '){
sb.append(s.charAt(begin));
}
begin++;
}
return sb;
}
}
方法二:代码随想录思路:①删除多余空格②整体翻转+单词翻转 = 单词顺序翻转
用String和char数组两种类型做的方法不一致——
用String变量实现翻转:
class Solution {
public String reverseWords(String s) {
//首先移除多余空格(初始化)
StringBuilder sb = removeSpaces(s);
System.out.println(sb);
//接着整体翻转
reverse(sb,0,sb.length()-1);
//最后局部翻转单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder removeSpaces(String s){
//动态字符串:找到合适的字符就append进新字符串
StringBuilder sb = new StringBuilder();
int l = 0;
int r = s.length()-1;
//剪枝
while(l<r && s.charAt(l)==' ')l++;
while(l<r && s.charAt(r)==' ')r--;
//注意需要添加新数组元素的情况,因为append的是left所以要允许left=right
while(l<=r){
//只要非“当前指向的是空格且新字符串sb的最后一位也是空格”情况
if(s.charAt(l)!=' ' || sb.charAt(sb.length()-1)!=' '){
sb.append(s.charAt(l));
}
l++;
}
return sb;
}
public void reverse(StringBuilder sb,int l,int r){
while(l<r){
char tmp = sb.charAt(r);
//不能直接等号复制改变,如sb.charAt(r) = sb.charAt(l);
sb.setCharAt(r,sb.charAt(l));
sb.setCharAt(l,tmp);
l++;
r--;
}
}
public void reverseEachWord(StringBuilder sb){
int l = 0;
for(int r = 0;r<=sb.length();r++){
if(r == sb.length() || sb.charAt(r) == ' '){ //右指针指向单词空格或数组末尾时逆转单词
reverse(sb,l,r-1);
l = r+1;
}
}
}
}
用chars数组实现翻转:
class Solution {
public String reverseWords(String s) {
char[] chars = s.toCharArray();
//首先移除多余空格(初始化)
chars = removeSpaces(chars);
//接着整体翻转
reverse(chars,0,chars.length-1);
//最后局部翻转单词
reverseEachWord(chars);
return new String(chars);
}
public char[] removeSpaces(char[] chars){
//数组:只能采用快慢指针法更新数组,最终输出新数组
int slow = 0; //新元素下标
//新元素
for(int fast = 0;fast<chars.length;fast++){
if(chars[fast] != ' '){
if(slow!=0){ //单词末尾增加一个空格
chars[slow++] = ' ';
}
//fast<chars.length要放在前面
//fast++是为了循环排除空格,并且跳出循环时slow正好指向单词或数组末尾
while(fast<chars.length && chars[fast]!=' '){
chars[slow++] =chars[fast++];
}
}
}
//最后返回更改大小的数组
char []newChars = new char[slow];
System.arraycopy(chars,0,newChars,0,slow);
return newChars;
}
public void reverse(char[] chars,int l,int r){
while(l<r){
char tmp = chars[r];
chars[r] = chars[l];
chars[l] = tmp;
l++;
r--;
}
}
public void reverseEachWord(char[] chars){
int l = 0;
for(int r = 0;r<=chars.length;r++){
if(r == chars.length || chars[r] == ' '){ //右指针指向单词空格或数组末尾时逆转单词
reverse(chars,l,r-1);
l = r+1;
}
}
}
}
卡码网55 右旋转字符串
题目链接:55.右旋转字符串
思路同上一题的翻转方法,先整体再局部
import java.util.Scanner;
public class Main{
//静态方法,无需实例化即可调用
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
int k = Integer.parseInt(reader.nextLine());
char[] chars = reader.nextLine().toCharArray();
int start = 0;
int end = chars.length-1;
//先整体翻转
reverse(chars,start,end);
//再翻转前k
reverse(chars,start,k-1);
//翻转后n-k个
reverse(chars,k,end);
String s = new String(chars);
System.out.println(s);
}
public static void reverse(char[] chars,int start,int end){
while(start<end){
char tmp = chars[end];
chars[end] = chars[start];
chars[start] = tmp;
start++;
end--;
}
}
}