随想录训练营Day8| 字符串, 344. Reverse String, 541. Reverse String II, 151. Reverse Words

186 阅读2分钟

随想录训练营Day8| 字符串, 344. Reverse String, 541. Reverse String II, 151. Reverse Words in a String, 151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串

标签: LeetCode闯关记


##1. 344. Reverse String ###1.1 题目

344. Reverse String

###1.2 解题思路

###1.3 遇到问题 无 ###1.4 算法实现

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        char temp = 0;
        while (left < right) {
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
}

###1.5 题目总结 解题耗时:30min ###1.6 相关题目


##2. 541. Reverse String II ###2.1 题目 题目:541. Reverse String II ###2.2 解题思路 for循环遍历+左右指针(重点:for循环的条件+判断 k<n<2k) ###2.4 实现代码

lass Solution {
    public String reverseStr(String s, int k) {
        //将字符串转化为char数组
        char[] ch = s.toCharArray();
        //注意for循环的trick: "i += 2*k"
        for (int i = 0; i < ch.length; i += 2*k) {
            int left = i;
            // 判断尾数够不够k个来取决right指针的位置(很巧妙)
            int right = Math.min(i + k - 1, ch.length - 1) ;
            char temp = 0;
            while(left < right){
                temp = ch[right];
                ch[right] = ch[left];
                ch[left] =temp;

                left++;
                right--;
            }
        }
        return new String(ch);
    }
}

###2.5 题目总结 解题耗时: 40min ###2.6 相关题目


##**3. 剑指Offer 05.替换空格 ** ###3.1 题目 相关链接 剑指Offer 05.替换空格

###3.2 解题思路 二分查找 ###3.3 遇到问题 无 ###3.4 算法实现 法1:新建StringBuilder 遍历原String,遇到空格则在新的StringBuilder上增加为"%20",否则直接复制原元素;

class Solution {
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == ' '){
                sb.append("%20");
            }else{
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}

法2:双指针法

class Solution {
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == ' '){
                sb.append("  ");
            }
        }
        //如果没有空格
        if(sb.length() == 0){
            return s;
        }

        //双指针
        int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
        s += sb.toString();
        int right = s.length() - 1;//右指针:指向扩展字符串的最后一个位置
        char[] chars = s.toCharArray();
        while(left >= 0){
            if(chars[left] == ' '){
                chars[right--] = '0';
                chars[right--] = '2';
                chars[right] = '%';
            }else{
                chars[right] = chars[left];
            }
            left--;
            right--;
            }
        
        return new String(chars);
        }
}

###3.5 题目总结 解题耗时:30min ###3.6 相关题目

##4. 151. Reverse Words in a String ###4.1 题目 相关链接 151. Reverse Words in a String

###4.2 解题思路 自己思考: 1.先用双指针法把多余的space取掉 2.新建一个StringBuilder,从后向前遍历原来的String,用左右指针. 左指针左移,在左指针遇到空格之前右指针保持不动;用来记录一个word,并写入新的StringBuilder中 ------搞复杂了 ###4.3 遇到问题 抄的答案解法4 ###4.4 算法实现

class Solution {
    public String reverseWords(String s) {
        char[] chars = s.toCharArray();
        chars = deleteExtraSpaces(chars);

        reverse(chars,0, chars.length - 1);

        reverseEachWord(chars);

        return new String(chars);

    }
    //清除多余的空格 运用快慢指针
    private char[] deleteExtraSpaces(char[] ch){
        int slow = 0;
        for(int fast = 0; fast < ch.length; fast++){
            if(ch[fast] != ' '){
                if(slow != 0){
                    ch[slow++] = ' ';
                }
                while(fast < ch.length && ch[fast] != ' '){
                    ch[slow++] = ch[fast++];
                }
            }
        }
        char[] newCh = new char[slow];
        System.arraycopy(ch,0,newCh,0,slow);
        return newCh;
    }

    //翻转整个字符串
    public void reverse(char[] chars,int left, int right){

        char temp = 0;
        while(left < right){
            temp = chars[right];
            chars[right] = chars[left];
            chars[left] = temp;
            left++;
            right--;
        }
    }

    //反转单词(难点: 判断一整个单词start 和 end的范围)
    private void reverseEachWord(char[] chars){
        int start = 0;
        for(int end = 0; end <= chars.length; end++){//end指向一个单词末尾的后一个位置
            if( end == chars.length || chars[end] == ' '){ //end == chars.length || chars[end] == ' '顺序不能改变,否则当end == chars.length,chars[end]先被判断的话会造成数组越界
                System.out.println(start + " " + chars[start]);;
                reverse(chars, start, end - 1);
                start = end + 1;
            }
        }
    }

}

###4.5 题目总结 解题耗时:1.5h 好难

###4.6 相关题目

##**5.剑指Offer58-II.左旋转字符串 ** ###5.1 题目 相关链接 剑指Offer58-II.左旋转字符串

###5.2 解题思路 巧妙: 整体反转 + 局部反转 ###5.3 遇到问题

###5.4 算法实现

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        reverse(chars,0,chars.length - 1);
        reverse(chars, 0 , chars.length - 1 - n);//注意右侧区间的取值
        reverse(chars, chars.length - n, chars.length - 1 );
        return new String(chars);
    }

    public void reverse(char[] chars, int left, int right){
        char temp = 0;
        while(left < right){
            temp = chars[right];
            chars[right] = chars[left];
            chars[left] = temp;
            left++;
            right--;
        }
    }
}

###5.5 题目总结 解题耗时:40min ###5.6 相关题目


##6. 今日心得 3.27补3.22 151.翻转字符串里的单词的细节好难