跳转至

字符串

相关理论:代码随想录 字符串

1. 反转字符串

link: LeetCode 344

思考:使用双指针

class Solution {

    public void reverseString(char[] s) {

        int left = 0, right = s.length-1;

        while(left < right){

            char temp = s[left];

            s[left] = s[right];

            s[right] = temp;



            left++;

            right--;

        }

    }

}

2. 反转字符串Ⅱ

link: LeetCode 541

思路:

对数组进行遍历,每一次 \(i\) 移动 \(2k\) 个字符, 然后判断 \(i+k\) 是否超过了数组长度,如果超过则全部反转,如果没超过则只反转 \([i, i+k]\)

class Solution {

    public String reverseStr(String s, int k) {

        // 将字符串转为字符数组

        char ch[] = s.toCharArray();

        // 使用i开始遍历数组

        for (int i=0; i<ch.length; i+=2*k){

            // 当剩余字符大于k, 反转前k个

            if (i + k < ch.length) revise(ch, i, i+k-1);

            // 如果剩余字符少于k, 全部反转

            else revise(ch, i, ch.length-1);

        }



        return new String(ch);

    }




    public void revise(char[] s, int i, int j){

        while(i < j){

            char temp = s[i];

            s[i] = s[j];

            s[j] = temp;

            i++;

            j--;

        }

    }

}

方法二:使用 Java中的 StringBuffer

class Solution {

    public String reverseStr(String s, int k) {

        StringBuffer resBuffer = new StringBuffer();

        for (int i=0; i<s.length(); i+=2*k){

            // 首先判断是否还有k个字符

            // 寻找第k个字符的索引, 如果剩余的字符少于k个字符, 则索引为最后的字符

            int firstK = i + k < s.length()? i+k : s.length();

            // 寻找第2k个字符的索引, 如果剩余的字符少于 2k 个字符, 则索引为最后的字符

            int secondK = i + 2*k < s.length()? i+2*k : s.length();



            // 反转[i, firstK), 使用String自带的reverse方法

            StringBuffer tempBuffer = new StringBuffer();

            // subString 是左边右开

            tempBuffer.append(s.substring(i, firstK));

            resBuffer.append(tempBuffer.reverse());



            // 如果firstK到secondK之间有元素, 则直接添加到 resBuffer 中

            resBuffer.append(s.substring(firstK, secondK));

        }



        return resBuffer.toString();

    }

}

3. 替换数字

link: 卡码网 54

思考:

如果直接在原字符串进行修改,则先确定修改后的字符串长度,然后使用双指针,从后向前修改

但是: Java 的 String 不能原地修改, 因此必须再定义新的 StringBuffer

import java.lang.*;

import java.util.*;

public class Main{

    public static void main (String[] args) {
        StringBuffer resBuffer = new StringBuffer();
        String s;
        Scanner sc = new Scanner(System.in);
        s = sc.nextLine();

        for (int i=0; i<s.length();i++){
            if (Character.isDigit(s.charAt(i))){
                resBuffer.append("number");
            }else {
                resBuffer.append(s.charAt(i));
            }
        }
        System.out.println(resBuffer.toString());
    }
}

4. 反转字符串里的单词

link: LeetCode 151

思考: 首先移除多余的空格,然后将整个字符串反转,然后将每个单词再次反转

class Solution {

    public String reverseWords(String s) {

      // 1. 首先通过双指针去除空格

      // 因为对原字符串的长度发生了更改, 因此需要返回

      StringBuilder sb = reverseSpace(s);

      // 2. 将整个字符串进行反转

      reverseString(sb, 0, sb.length()-1);

      // 3. 反转每一个单词

      reverseEachWord(sb);



      return sb.toString();




    }

    // 反转整个字符串

    // 左闭右闭

    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 void reverseEachWord(StringBuilder sb){

        int len = sb.length();

        // start 定义每一个单词的起始位置, 通过start遍历字符串, 找到每一个单词的起始位置

        // end定义每一个单词后面的空格的位置

        int start = 0, end = 1;

        while(start<len){

            // 寻找这个单词后面的空格的索引

            while (end < len && sb.charAt(end) != ' ') end++;

            // 寻找到单词的空格后

            // 反转这个单词

            reverseString(sb, start, end-1);

            start = end+1;

            end = end+2;

        }

    }



    // 去除空格

    public StringBuilder reverseSpace(String ss){

        // 先去除前面的元素和后面的元素

        int start=0;

        int len=ss.length()-1;

        while(ss.charAt(start) == ' ') start++;

        while(ss.charAt(len) == ' ') len--;




        // 定义需要返回的结果

        StringBuilder sb = new StringBuilder();

        // 寻找满足条件的元素

        while(start <= len){

            if (ss.charAt(start) != ' ' || ss.charAt(start-1) != ' ')

            {

                sb.append(ss.charAt(start));

            }

            start++;

        }



        return sb;




    }

}
class Solution {

    public String reverseWords(String s) {

       String ss[] = s.trim().split("\\s+");



       StringBuilder resBuilder = new StringBuilder();

       for (int i=ss.length-1; i>=0; i--){

            resBuilder.append(ss[i]);

            if (i > 0) resBuilder.append(" ");

       }



       return resBuilder.toString();



    }

}

5. 右旋转字符串

link : 卡码网 55

思考: 如果不申请额额外的空间,只在原字符串上操作

将后面的k个字符移动到前面,相当于将字符串向后移动 k 位,可以将字符串分为两部分

如果直接将整个字符串反转:

此时第一段和第二段正好是想要的,只不过他们是倒序的,再将他们分别反转

import java.lang.*;
import java.util.*;

public class Main{
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        int k = Integer.parseInt(sc.nextLine());
        String s = sc.nextLine();

        // System.out.println(k + " " + s);
        char ss[] = s.toCharArray();
        // 整体反转
        reverseChar(ss, 0, ss.length-1);
        // System.out.println(ss);
        // 反转第一段
        reverseChar(ss, 0, k-1);
        // 反转第二段
        reverseChar(ss, k, ss.length-1);

        System.out.println(ss);


    }

    // 对字符串进行反转 左闭右闭
    public static void reverseChar(char[] ss, int left, int right){
        while(left < right){
            char temp = ss[right];
            ss[right] = ss[left];
            ss[left] = temp;
            left++;
            right--;
        }

    }
    }