【Java】代码随想录字符串第八天| LeetCode344 反转字符串、LeetCode541 反转字符串ii、卡码网54 替换数字、LeetCode151 翻转字符串里的单词

今日任务 
  •  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--;
        }
    }
}

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值