《代码随想录》--字符串

《代码随想录》--字符串

  • 344.反转字符串
  • 541.反转字符串 Ⅱ
  • 替换数字
  • 151.反转字符串里的单词

344.反转字符串

leetcode链接

《代码随想录》--字符串_第1张图片

代码

  • 双指针
class Solution {
    public void reverseString(char[] s) {
        int right = s.length - 1;
        int left = 0;
        char temp = ' ';
        while(left < right){
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
}
  • 异或运算进行交换
class Solution {
    public void reverseString(char[] s) {
        int l = 0;
        int r = s.length - 1;
        while (l < r) {
            s[l] ^= s[r];  //构造 a ^ b 的结果,并放在 a 中
            s[r] ^= s[l];  //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
            s[l] ^= s[r];  //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
            l++;
            r--;
        }
    }
}

分析

  • 法一
    • 常规的双指针进行交换。
  • 法二
    • 离散数学基础:
    • 交换律:A ^ B = B ^ A;
      结合律:A ^ (B ^ C) = (A ^ B) ^ C;
      恒等律:X ^ 0 = X;
      归零律:X ^ X = 0;
      自反:A ^ B ^ B = A ^ 0 = A;
      对于任意的 X: X ^ (-1) = ~X;
      如果 A ^ B = C 成立,那么 A ^ C = B,B ^ C = A;

541.反转字符串 Ⅱ

leetcode链接
《代码随想录》--字符串_第2张图片

代码

  • 方法一
class Solution {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        int n = arr.length;
        for(int i = 0;i < n;i += 2*k){
            int l = i,r = k-1+i; 
            int t = n - l; //字符串剩下的元素
            if(t < k) reverse(arr,l,n-1); 
            else reverse(arr,l,r);
        }
        return new String(arr);
    }
    public void reverse(char[] s,int l,int r){
        char temp = ' ';
        while(l < r){
            temp = s[l];
            s[l] = s[r];
            s[r] = temp;
            r--;
            l++;
        }
    }
}

分析

  • 将此题思考成 一个字符串分成多份字符串,其中一些字符串需要进行交换。所以将交换的代码独立出来。
  • 再用一个循环来找需要反转的字符串是哪些。

替换数字

卡码网地址
《代码随想录》--字符串_第3张图片

代码

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder();
        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);
    }
}

分析

  • 直接遍历字符串,有数字添加number

151.反转字符串里的单词

leetcode链接
《代码随想录》--字符串_第4张图片

代码

  • 解法一
class Solution {
    public String reverseWords(String s) {
        //1.去多余空格
        StringBuilder sb = removeSpace(s);
        //2.反转整个字符串
        reverseString(sb,0,sb.length()-1);
        //3.反转每个单词
        return reverseWord(sb).toString();
    }
    public StringBuilder removeSpace(String s){
        int start = 0;
        int end = s.length() - 1;
        //删除前置空格
        while(s.charAt(start) == ' ') start++;
        //删除后置空格
        while(s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while(start <= end){
            char c = s.charAt(start);
            if(c != ' ' || sb.charAt(sb.length() - 1) != ' '){
                sb.append(c);
            }
            start++;
        }
        return sb;
    }
    public void reverseString(StringBuilder sb,int start,int end){
        while(start < end){
            char temp = sb.charAt(start);
            sb.setCharAt(start,sb.charAt(end));
            sb.setCharAt(end,temp);
            start++;
            end--;
        }
    }
    public StringBuilder reverseWord(StringBuilder sb){
        int start = 0;
        int end = 1;
        int n = sb.length();
        while(start < n){
            while(end < n && sb.charAt(end) != ' '){
                end++;
            }
            reverseString(sb,start,end-1);
            start = end + 1;
            end = start + 1;
        }
        return sb;
    }
}
  • 解法二
class Solution {
    public String reverseWords(String s) {
        //将字符串转为字符数组
        char[] a = s.toCharArray();
        //定义一个用于接收转换字符后的数组
        char[] b = new char[a.length+1];//因为下面的算法会在每个单词末尾添加一个空格,所以多设置一个位置,避免越界
        //记录新数组的最后一个元素的索引
        int resArr = 0;
        //用于从尾到头遍历的指针
        int i = a.length - 1;
        while(i >= 0){
            //删除原数组中的空格,让i指向单词的尾字母
            while(i >= 0 && a[i] == ' ') i--;
            //保存这个尾字母的索引
            int j = i;
            while(i >= 0 && a[i] != ' ') i--; //记住 现在j指向一个单词的尾字母,i指向了一个单词的首字母的前一位
            //现在可以添加单词进数组了,+1 是因为要指向单词首字母
            for(int k = i + 1;k <= j;k++){
                b[resArr++] = a[k];
                if(k == j){ //遍历到最后一个位置加空格
                b[resArr++] = ' ';
                }
            }
        }
        if(resArr == 0){
            return "";
        }else{
            return new String(b,0,resArr-1);
        }
    }
}

分析

  • 方法一(整体反转+局部反转)
    • 先移除多余的空格,移除全部前置和后置空格,中间空格只留下一个
    • 再反转整个字符串
    • 最后反转每个单词
  • 方法二(见注释)

你可能感兴趣的:(代码随想录,java,数据结构)