Loading

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

题目

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

思路1(原地翻转)

  • 先将前n个进行翻转,再将后n个进行翻转,最后再整体翻转一遍
  • 我们把他看成两个部分,然后对每个部分都是一个整体,内部不需要翻转,因此我们可以把这题可以看作是剑指 Offer 58 - I. 翻转单词顺序只有两个单词的情况

代码

class Solution {
    public String reverseLeftWords(String s, int n) {
        // 将String类型转换成char[]类型
        char[] arr = s.toCharArray();
        int length = arr.length;
        // 翻转前半部分
        reverse(arr, 0, n-1);
        // 翻转后半部分
        reverse(arr, n, length-1);
        // 整体再翻转一遍
        reverse(arr, 0, length-1);
        // 将翻转结束的字符数组转化成字符串
        return new String(arr);
    }

    // 翻转指定范围的字符串
    public void reverse(char[] arr, int begin, int end) {
        while (begin < end) {
            char temp = arr[begin];
            arr[begin] = arr[end];
            arr[end] = temp;
            begin++;
            end--;
        }
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\)
  • 空间复杂度:\(O(1)\),因为Java不支持对字符串的修改,所以转化成字符数组,实际上空间复杂度还是O(1)

思路2(字符串遍历拼接)

  • 先遍历n到末尾的字符串,然后再遍历0到n-1的字符串,将这两个字符串拼接起来就得到了左旋转字符串。这两次遍历使用到了两个for循环,我们可以使用求余符号,合并到一个for循环中

代码

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();

        /*
        for (int i = n; i < s.length(); i++) {
            sb.append(s.charAt(i));
        }
        for (int i = 0; i < n; i++) {
            sb.append(s.charAt(i));
        }
        */
        for (int i = n; i < s.length() + n; i++) {
            sb.append(s.charAt(i % s.length()));
        }

        return sb.toString();
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\)
  • 空间复杂度:\(O(N)\)
posted @ 2021-11-02 16:50  linzeliang  阅读(31)  评论(0编辑  收藏  举报