Day7 | 344反转字符串&541反转字符串Ⅱ&剑指Offer 05.替换空格&剑指Offer58-II.左旋转字符串

94 阅读3分钟

反转字符串 LeetCode 344

题目链接:[LeetCode 454 - 简单]

思路

看到了题意中的①原地修改输入数组②使用O(1)的额外空间,就想到使用双指针的方法来解决。

双指针:

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

总结

可以将while循环改为for循环,代码可以简洁。

反转字符串Ⅱ LeetCode 541

题目链接:[LeetCode 541 - 简单]

思路

看到题目的第一想法:①如果字符串大于k,则反转前k个。②如果字符串小于k,字符串全部反转。③如果字符串大于2k,能被2k整除的部分反转前k个,剩余部分按照①②的情况执行。

双指针:

java
class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for(int i=0;i<ch.length;i+=2*k){
            int start = i;
            int end = Math.min(ch.length-1,i+k-1);
            while(start<end){
                char tmp = ch[start];
                ch[start++] = ch[end];
                ch[end--] = tmp;
            }
        }
        return new String(ch);
    }
}

总结

学习到以下几点 ①为什么int end = Math.min(ch.length-1,i+k-1);部分使用的是i+k-1而不是i+k,因为前k个如果不减去1的话,那么反转的有k+1个元素。 ②使用char[] ch = s.toCharArray()和new String(ch),就是将字符串转化为char数组,然后将char数组转化为字符串。

剑指Offer 05.替换空格

题目链接:[剑指Offer 05.替换空格 - 简单]

思路

使用StringBuilder或者将String转化为char[]数组

O(n)的时间复杂度:

java
class Solution {
    public String pathEncryption(String path) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<path.length();i++){
            if(path.charAt(i)=='.'){
                sb.append(' ');
            }else{
                sb.append(path.charAt(i));
            }
        }
        return new String(sb);
    }
}

总结

为什么".".equals(path.charAt(i))会发生错误?需要使用".".equals(String.valueOf(s.charAt(index)))进行替换。

反转字符串中的单词 LeetCode 151

题目链接:[LeetCode 151 - 中等]

思路

有以下几点需要考虑到:①如何处理单词之间或者字符串首尾的多余空格②如何解决单词反转问题

使用StringBuilder:

java
class Solution {
    public String reverseWords(String s) {
        String ch = removeSpace(s);

        StringBuilder sb = new StringBuilder();
        int right = ch.length();
        for(int i=ch.length()-1;i>=0;i--){
            if(ch.charAt(i)==' '){
                sb.append(ch.substring(i+1,right)+" ");
                right = i;
            }
        }
        sb.append(ch.substring(0,right));
        return new String(sb);
    }
    private String 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 new String(sb);
    }
}

总结

可以使用先将字符串内的多余空格去除,然后将整个字符串反转,然后再反转每一个单词。(可以有使用数组和使用StringBuilder的版本)

剑指Offer58-II.左旋转字符串

题目链接:[剑指Offer58-II.左旋转字符串 - 简单]

思路

有以下几点需要考虑到:①如何处理target比password的长度要大②如何解决右旋字符串的情况

使用StringBuilder:

java
class Solution {
    public String dynamicPassword(String password, int target) {
        int num = password.length();
        int targetNum = target % num;

        StringBuilder sb = new StringBuilder();
        for(int i=targetNum;i<num;i++){
            sb.append(password.charAt(i));
        }
        for(int i=0;i<targetNum;i++){
            sb.append(password.charAt(i));
        }
        return new String(sb);
    }
}

总结

简单粗暴版本:

class Solution {
    public String dynamicPassword(String password, int target) {
        StringBuilder res=new StringBuilder();
        res.append(password.substring(target,password.length()));
        res.append(password.substring(0,target));
        return res.toString();

    }
}

网站上的版本: 反转整个字符串->反转前一段字符串->反转后一段字符串