代码随想录Day10

题目列表

  • 151.翻转字符串里的单词
  • 卡码网:55.右旋转字符串
  • 28.实现 strStr()
  • 459.重复的子字符串

解题过程

151.翻转字符串里的单词

题目描述

image

解题思路

首先去除字符串中多余的空格,首尾空格要去掉,中间多余的空格要去掉,如果当前字符 c 不是空格,直接添加。如果 c 是空格,但 sb 的最后一个字符不是空格。
然后将整个字符串反转,再分别将每一个单词反转,这样就可以得到正确的结果。

代码展示

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = removeSpace(s);
        reverse(sb,0,sb.length()-1);
        reverseWord(sb);

        return sb.toString();
    }
    private 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;
    }
    private void reverse(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--;
        }
    }
     private void reverseWord(StringBuilder sb){
        int start = 0;
        int end = 1;
        while(start <= sb.length() - 1){
            // && 短路特性
            while(end < sb.length()&& sb.charAt(end) != ' '){
                end++;
            }
            reverse(sb,start,end-1);
            start = end + 1;
            end = start + 1;
        }
    }
}

卡码网:55.右旋转字符串

题目描述

image

解题思路

和之前的反转字符串里的单词有点类似。题目中说的右旋,实际上也就是让前一段子串和后一段子串交换位置,也就是说可以先让整个字符串都反转,此时末尾待“右旋”的子串就在开头了,这时只需要将两个子串分别反转成正确的顺序即可。

代码展示

import java.util.*;

class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int k = scanner.nextInt();
        scanner.nextLine(); //消耗\n
        String s = scanner.nextLine();

        char[] chs = s.toCharArray();
        reverse(chs, 0, s.length() - 1);
        reverse(chs, 0, k - 1);
        reverse(chs, k, s.length() - 1);
        System.out.println(new String(chs));
    }
    public static void reverse(char[] chars,int start, int end){
        while(start < end){
            char temp = chars[start];
            chars[start] = chars[end];
            chars[end] = temp;
            start++;
            end--;
        }
    }
}

28.实现 strStr()

题目描述

image

解题思路

KMP
浅显理解,达到降低时间复杂度的方法是:不再重复匹配“当前不一致的字符”之前的“已经判断为一致的子字符串”,而要达到不重复判断的方法是:记录“当前不一致的字符”之前的子字符串里的相等的前后缀。

代码展示

class Solution {
    public int strStr(String haystack, String needle) {
        int l1 = haystack.length();
        int l2 = needle.length();

        //构造前缀表
        int[] next = new int[l2];
        next[0] = 0;
        for(int j = 0, i = 1; i < l2; i++){
            while(j > 0 && needle.charAt(j) != needle.charAt(i)){
                j = next[j - 1];
            }
            if(needle.charAt(j) == needle.charAt(i)){
                next[i] = j + 1;
                j++;
            }
        }

        //匹配
        for(int i = 0, j = 0; i < haystack.length(); i++){
            while(j > 0 && haystack.charAt(i) != needle.charAt(j)){
                j = next[j - 1];
            }
            if(haystack.charAt(i) == needle.charAt(j)){
                j++;
            }
            if(j == l2){
                return i - l2 + 1;
            }
        }
        return -1;
    }
}

459.重复的子字符串(待做)

题目描述

image

解题思路

注意事项

代码展示


参考资料

代码随想录

posted @ 2025-05-06 15:27  cbdsszycfs  阅读(86)  评论(0)    收藏  举报