代码随想录算法训练营第8天| 344.反转字符串 、541. 反转字符串II、卡码网:54.替换数字 、151.翻转字符串里的单词 、卡码网:55.右旋转字符串

344.反转字符串

题目链接:344. 反转字符串 - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
视频讲解:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili
解题思路:

class Solution {
    public void reverseString(char[] s) {
        for (int i = 0, j = s.length - 1; i < s.length / 2; i++, j--) {
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
        }       
    }
}


时间复杂度:O(n)
该题总结:这题给我一种今天会很快乐地结束的感觉,只能说我的感觉很不准。

541. 反转字符串II

题目链接:541. 反转字符串 II - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
解题思路:

class Solution {
   public String reverseStr(String s, int k) {
        char[] ret = s.toCharArray();
        for (int i = 0; i < ret.length; i += 2 * k) {
            int start = i;
            //让start从i开始向右走
            int end = Math.min(ret.length - 1, start + k - 1);
            //判断是否循环到了末尾
            while (start < end) {
                char tmp = ret[start];
                ret[start] = ret[end];
                ret[end] = tmp;
                start++;
                end--;
                }
        }
        return new String(ret);
    }
}


时间复杂度:O(n)
该题总结:这道题本来是不难的,但我做了半天才做出来的原因是java刚开始用,什么方法都不太会用,导致浪费了很多时间,要是能像到最后一题似的开窍了知道写个reverse方法的话就不用费这么长时间了。

卡码网:54.替换数字

题目链接:题目页面 (kamacoder.com)
文档讲解:代码随想录 (programmercarl.com)
解题思路:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        char[] old = s.toCharArray();
        //将s转化为char[]型字符串便于遍历
        int count = 0;
        //用于记录字符串大小来创建新的字符串
        for (char c : old) {
            if (c >= '0' && c <= '9') {
                count++;
            }
        }
        //通过遍历计算出字符串的大小
        char[] ret = new char[old.length + count * 5];
        //创建char[]字符串便于增改,这里是加5不是加6,因为原本数字在老的字符串里就已经占了一位的长度了
        int i = 0;
        //该指针指向旧字符串开头
        int j = 0;
        //该指针指向新字符串开头
        while (i < old.length) {
            if (old[i] >= '0' && old[i] <= '9') {
                ret[j] = 'n';
                ret[j + 1] = 'u';
                ret[j + 2] = 'm';
                ret[j + 3] = 'b';
                ret[j + 4] = 'e';
                ret[j + 5] = 'r';
                i++;
                j += 6;
            } else {
                ret[j] = old[i];
                i++;
                j++;
            }
        }
        String result = new String(ret);
        System.out.print(result);
    }
}


时间复杂度:O(n)
该题总结:回头看还是一道简单题,但也调试了很久才做好,只能说加油了。

151.翻转字符串里的单词

题目链接:151. 反转字符串中的单词 - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
视频讲解:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili
解题思路:

//需要三个方法:
//1:去除多余空格
//1.1:将数组重塑成合适的大小
//2:反转字符串
//3:反转单词
class Solution {
   public String reverseWords(String s) {
        char[] ret = removeblanks(s.toCharArray());
        //去除多余空格
        reverse(ret, 0, ret.length - 1);
        //反转字符串
        reverseEachWord(ret);
        //反转单词
        return new String(ret);
        }


    public char[] removeblanks(char[] s) {
        int slow = 0;
        //将慢指针放在循环体外以便重塑数组长度时使用
        for (int fast = 0; fast < s.length; fast++) {
            if (s[fast] != ' ') {
                //让快指针跳过前面的空格
                if (slow != 0) {
                    s[slow] = ' ';
                    slow++;
                    //让慢指针给除第一个单词外的每个单词后加上空格
                }
                while (fast < s.length && s[fast] != ' ') {
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                    //将每个单词放在去空格后的位置
                }
            }

        }
        char[] ret = new char[slow];
        System.arraycopy(s, 0, ret, 0, slow);
        //重塑数组长度
        return ret;
    }

    public void reverse(char[] s, int left, int right) {

        //这里在函数参数中设置左右指针是因为反转单词时可复用
        while (left < right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;
        }
        //反转字符串
    }

    public void reverseEachWord(char[] s) {
        int start = 0;
        for (int end = 0; end <= s.length; end++) {
            //这里小于等于是为了最后一次循环的顺利进行
            if (end == s.length || s[end] == ' ') {
                reverse(s, start, end - 1);
                start = end + 1;
            }
        }
    }
}


时间复杂度:O(n)
该题总结:这道题是真给我难住了,总共三个大步骤,每个对当时做题的我来说都是重量级的困难,甚至回头看都感觉这题需要注意的地方很多,不看题解写第二遍都不一定能写对,也是今天耗费时长最长的题,做完倒是感觉很有收获,但是做的时候确实难死了给我。

卡码网:55.右旋字符串

题目链接:题目页面 (kamacoder.com)
文档讲解:代码随想录 (programmercarl.com)
解题思路:

import java.lang.String;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int spilt = sc.nextInt();
        sc.nextLine();
        String s = sc.nextLine();
        char[] c = s.toCharArray();
        reverse(c, 0, c.length - 1);
        //整个字符串逆序
        reverse(c, 0 ,spilt - 1);
        //逆序split之前的字符串
        reverse(c, spilt, c.length - 1);
        //逆序spilt之后的字符串
        String result = new String(c);
        System.out.print(result);
    }

    public static void reverse(char[] c, int start, int end) {
        while (start < end) {
            char tmp = c[start];
            c[start] = c[end];
            c[end] = tmp;
            start++;
            end--;
        }
    }
}


时间复杂度:O(n)
该题总结:写到这题的时候就突然想到写一个reverse方法了,写出来之后做这道题就是手到擒来了,整体reverse+前后两段reverse,so EZ了直接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值