Bootstrap

字符串的反转——344、541、557、151

344. 反转字符串

解法一、遍历前半段

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

 解法二、双指针

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

作者:力扣官方题解
链接:https://leetcode.cn/problems/reverse-string/solutions/439034/fan-zhuan-zi-fu-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

541. 反转字符串 II

解法一、正常遍历

注意:最后2n的部分,先天满足,但需要判断边界。

class Solution {
    public String reverseStr(String s, int k) {
        char[] cs = s.toCharArray();
        int n = cs.length / k;//一共有几个n
        for (int i = 0; i <= n; i += 2) {
            reverse(cs, i * k, Math.min((i + 1) * k, cs.length));
        }
        return new String(cs);
    }

    public void reverse(char[] cs, int l, int r) {
        l--;
        while (++l < --r) {
            char t = cs[l];
            cs[l] = cs[r];
            cs[r] = t;
        }
    }
}

 
557. 反转字符串中的单词 III

解法一、正常遍历

拆成字符串组再做。可以说是非常赘余了

class Solution {
    public String reverseWords(String s) {
        String[] temp = s.split(" ");
        String res = "";
        int len = temp.length;
        for(int i = 0;i < len;i++){
            temp[i] = reverse(temp[i]);
            res = res + temp[i];
            if(i != len - 1){
                res += " ";
            }
        }
        return res;
    }
    public String reverse(String s){
        int len = s.length();
        char[] a = new char[len];
        for(int i = 0;i < len;i++){
            a[i] = s.charAt(i);
        }
        for(int i = 0;i < len / 2;i++){
            char temp = a[len - i - 1];
            a[len - i - 1] = a[i];
            a[i] = temp;
        }
        return new String(a);
    }
}

解法二、各api

split,StringBuffer的reverse,String.join

 class Solution{ 
    public String reverseWords(String s) {
        String[] split = s.split(" ");
        for (int i=0; i<split.length; i++) {
            split[i] = new StringBuffer(split[i]).reverse().toString();
        }
        return String.join(" ", split);
    }
 }


151. 反转字符串中的单词

方法一、Api与正则表达式

//s+可以精确切分出各字符串,相较于直接空格为区分符优越,可去掉连续空格的情况。

class Solution {
    public String reverseWords(String s) {
        // 除去开头和末尾的空白字符
        s = s.trim();
        // 正则匹配连续的空白字符作为分隔符分割
        List<String> wordList = Arrays.asList(s.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}

 

方法二、正常遍历

源自题解评论区。之前自己的思路是用chat[]做,StringBuilder还是更优越

class Solution {
    public String reverseWords(String s) {
        int start, end;                       // 每个单词的开始和结束索引(左闭右开)
        StringBuilder sb = new StringBuilder();
        for (int i = s.length() - 1; i >= 0; i--) {
            if (s.charAt(i) == ' ') continue;   //跳过空格
            end = i + 1;                        //找到结束索引
            while (i >= 0 && s.charAt(i) != ' ') i--;   //跳过空格
            start = i + 1;                      //找到开始索引         
            for (int j = start; j < end; j++)   //将每个单词按开始结束索引赋值到StringBuilder
                sb.append(s.charAt(j));
            sb.append(' ');                     //加上单词间的空格
        }
        sb.deleteCharAt(sb.length() - 1);       //删掉最后一个多余的空格
        return sb.toString();
    }
}

方法三、双端队列

第一次看到用到队列的数据结构

class Solution {
    public String reverseWords(String s) {
        int left = 0, right = s.length() - 1;
        // 去掉字符串开头的空白字符
        while (left <= right && s.charAt(left) == ' ') {
            ++left;
        }

        // 去掉字符串末尾的空白字符
        while (left <= right && s.charAt(right) == ' ') {
            --right;
        }

        Deque<String> d = new ArrayDeque<String>();
        StringBuilder word = new StringBuilder();
        
        while (left <= right) {
            char c = s.charAt(left);
            if ((word.length() != 0) && (c == ' ')) {
                // 将单词 push 到队列的头部
                d.offerFirst(word.toString());
                word.setLength(0);
            } else if (c != ' ') {
                word.append(c);
            }
            ++left;
        }
        d.offerFirst(word.toString());

        return String.join(" ", d);
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/reverse-words-in-a-string/solutions/194450/fan-zhuan-zi-fu-chuan-li-de-dan-ci-by-leetcode-sol/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

碎碎念

  • 熟悉了部分数据结构和api,初步了解到队列
  • 感觉最近状态不好。。反思,意识到代码熟练度实际上还是很低,上午简单题写破防了,不过慢慢来吧
;