代码随想录算法训练营第九天 |●151.翻转字符串里的单词●卡码网:55.右旋转字符串●28. 实现 strStr()●459.重复的子字符串●字符串总结 ●双指针回顾

151.翻转字符串里的单词

思路:看题第一眼是用split() Method,但面试的时候,肯定不是这个难度。还有要注意的一点是单词之前只能有一个space,此外leading space和tailing space也需要移除。

我的想法是先遍历字符串,去掉多余的space。 再整体翻转字符串。最后遍历字符串,将每个word进行翻转。 和代码随想录的方法一相同。

疑问:解题时,我们允许用什么样的内置函数? 如果trim()可以用的话,那么第一边遍历可以省略,在翻转word时处理words之前多余的空格。

class Solution {
    public String reverseWords(String s) {
        //remove extra spaces
        int left = 0;
        int right = s.length() - 1;
        while(s.charAt(left) == ' ') left++;
        while(s.charAt(right) == ' ') right--;
        StringBuilder str = new StringBuilder();
        while(left <= right){
            if(s.charAt(left) != ' ' || s.charAt(left-1) != ' '){
                str.append(s.charAt(left));
            }
            left++;
        }
        //reverse the whole string
        reverseString(str, 0, str.length()-1);
        //reverse each word
        int start = 0; 
        int end = start + 1;
        while(start < str.length()){
            while(end < str.length() && str.charAt(end) != ' ') end++;
            reverseString(str, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
        return str.toString();
        
    }
    private void reverseString(StringBuilder str, int left, int right){
        while(left < right){
            char temp = str.charAt(left);
            str.setCharAt(left, str.charAt(right));
            str.setCharAt(right, temp);
            left++;
            right--;
        }
    }
}

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

思路: 最直接的方法就是模拟, 定义一个StringBuilder str,把字符串分成两部分[0, len - n - 1] 和 [ len - n, len - 1],先遍历第二部分,依次把元素append到str的尾部,然后依次加入第一部份的元素。

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        String str = scanner.nextLine();
        
        char[] chars = str.toCharArray();
        int len = chars.length ;
        // [0, len - n - 1] [ len - n, len - 1]
        StringBuilder res = new StringBuilder();
        for(int i = len - n; i < len; i++){
            res.append(chars[i]);
        }
        for(int i = 0; i < len - n; i++){
            res.append(chars[i]);
        }
        System.out.println(res);
    }
}

运行时间:

1358ms

消耗内存:

14364kb

第二个方法用翻转的方法,还是把字符串分成两部分,先整体翻转,再分别翻转第一部份和第二部分。

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        String str = scanner.nextLine();
        
        char[] chars = str.toCharArray();
        int len = chars.length ;
        reverse(chars, 0,len - 1);
        reverse(chars, 0, n - 1);
        reverse(chars, n, len - 1);
        System.out.println(chars);
    }
    private static void reverse(char[] chars, int start, int end){
        while(start < end){
            char temp = chars[start];
            chars[start++] = chars[end];
            chars[end--] = temp;
        }
    }
}

运行时间:

1615ms

消耗内存:

14164kb

28. 实现 strStr()

459.重复的子字符串

代码写出来了,但是KMP还是挺迷糊的,属于一看就会,一写就废。今天时间不太够,我这周有时间的时候再攻克一下。

字符串总结

151的疑问:解题时,我们允许用什么样的内置函数?
答:如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。(代码随想录)对库函数要了解底部实现的原理和时间复杂度。

双指针回顾

双指针法在数组,链表和字符串中很常用。

数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

数组删除操作的问题,从前向后进行操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值