代码随想录算法训练营 day 8: 344.反转字符串 | 541. 反转字符串II | 剑指Offer 05.替换空格 | 151. | 剑指Offer58

70 阅读2分钟

344. Reverse String

Write a function that reverses a string. The input string is given as an array of characters s.

You must do this by modifying the input array in-place with O(1) extra memory.

 

Example 1:

Input: s = ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]

Example 2:

Input: s = ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]

 

Constraints:

没什么说的,左右双指针对向移动,交换元素即可。

代码:

class Solution {
    public void reverseString(char[] s) {
        if(s.length == 1) {
            return;
        }
        int left = 0;
        int right = s.length - 1;

        while(left < right) {
            char c = s[left];
            s[left] = s[right];
            s[right] = c;

            left++;
            right--;
        }

        return;
    }
}

541. Reverse String II

Given a string s and an integer k, reverse the first k characters for every 2k characters counting from the start of the string.

If there are fewer than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and leave the other as original.

 

Example 1:

Input: s = "abcdefg", k = 2
Output: "bacdfeg"

Example 2:

Input: s = "abcd", k = 2
Output: "bacd"

 

Constraints:

  • 1 <= s.length <= 104
  • s consists of only lowercase English letters.
  • 1 <= k <= 104

反转字符串的变形,控制好边界条件即可。 代码:

class Solution {
    public String reverseStr(String s, int k) {
        int len = s.length();
        char[] ch = s.toCharArray();

        int left = 0;
        int right = len < k ? len - 1 : k - 1;
        int offset = 0;

        while(offset < len) {
            left = offset;
            right = offset + k > len ? len - 1: offset + k - 1;
            while(left < right) {
                char tc = ch[left];
                ch[left] = ch[right];
                ch[right] = tc;

                left++;
                right--;
            }

            offset += 2*k;
        }

        String ans = new String(ch);

        return ans; 
    }
}

剑指 Offer 05. 替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

 

示例 1:

输入: s = "We are happy."
输出: "We%20are%20happy."

 

限制:

0 <= s 的长度 <= 10000

剑指OFFER系列英文版力扣没有。题目没什么说的,StringBuilder append很轻松。回头要看一下不用StringBuilder的双指针法。 代码:

class Solution {
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();

        for(char c : s.toCharArray()) {
            if(c == ' ') {
                sb.append("%20");
            }
            else {
                sb.append(c);
            }
        }

        return sb.toString();

        
    }
}

151. Reverse Words in a String

Given an input string s, reverse the order of the words.

word is defined as a sequence of non-space characters. The words in s will be separated by at least one space.

Return a string of the words in reverse order concatenated by a single space.

Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.

 

Example 1:

Input: s = "the sky is blue"
Output: "blue is sky the"

Example 2:

Input: s = "  hello world  "
Output: "world hello"
Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

Input: s = "a good   example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

 

Constraints:

  • 1 <= s.length <= 104
  • s contains English letters (upper-case and lower-case), digits, and spaces ' '.
  • There is at least one word in s.

这题费了好大劲儿,二刷要注意。主要卡在Remove Extra Space功能上没想清楚。快慢指针还是不熟练。 代码:

class Solution {
    public char[] removeExtraSpaces(char[] ch) {
        int slow = 0;

        for(int i=0; i<ch.length; i++) {
            if(ch[i] != ' ') {
                if(slow != 0) {
                    ch[slow++] = ' ';
                }
                while(i<ch.length && ch[i] != ' ') {
                    ch[slow++] = ch[i++];
                }
            }
        }
        ch = Arrays.copyOf(ch, slow);

        return ch;
    }
    public String reverseWords(String s) {
        char[] ch = s.toCharArray();

        int left = 0;
        int right = ch.length - 1;

        //while(ch1[left] == ' ') left++;
        //while(ch1[right] == ' ') right--;

        //System.out.println("left:" + left + ", right: " + right);

        //left = 0; 
        //right = 0;

        ch = removeExtraSpaces(ch);
        //System.out.println(ch);

        left = 0; 
        right = ch.length - 1;

        while(left < right) {
            char tc = ch[left];
            ch[left] = ch[right];
            ch[right] = tc;
            left++;
            right--;
        }

        left=0;
        right=0;
        for(int i=0; i<=ch.length; i++) {
            if(i == ch.length || ch[i] == ' ') {
                right = i - 1;
                while(left < right) {
                    char tc = ch[left];
                    ch[left] = ch[right];
                    ch[right] = tc;
                    left++;
                    right--;
                }
                left = i + 1;
            }

        }
        String ans = new String(ch);
        return ans;

    }
}

剑指 Offer 58 - II. 左旋转字符串

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"

示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"

 

限制:

  • 1 <= k < s.length <= 10000

对Java来说这题总归做不成O(1)的空间复杂度。 看了Carl的写法才来写的。三次旋转很巧妙。 前部分反转,后部分反转,再整体反转,也能达到左旋的效果。

class Solution {
    public String reverseLeftWords(String s, int n) {
        String str1 = s.substring(0,n);
        String str2 = s.substring(n, s.length());

        StringBuilder sb1 = new StringBuilder(str1).reverse();
        str2 = new StringBuilder(str2).reverse().toString();

        sb1.append(str2);
        sb1.reverse();

        str1 = sb1.toString();

        return str1;


    }
}