【LeetCode】左旋转字符串Java题解 | Java 刷题打卡

本文正在参加「Java主题月 – Java 刷题打卡」,详情查看 活动链接

题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串”abcdefg”和数字2,该函数将返回左旋转两位得到的结果”cdefgab”。

 

示例 1:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
复制代码

思路分析

  • 这是一道字符串相关的题目,题意容易理解。可以直接按照题意循环解决,也可以调用系统函数 substring() 解决。

AC代码

    public String reverseLeftWords(String s, int n) {
        int length = s.length();
        n %= length;
        StringBuilder ans = new StringBuilder();
        for (int i = n; i < length; i++) {
            ans.append(s.charAt(i));
        }
        for (int i = 0; i < n; i++) {
            ans.append(s.charAt(i));
        }
        return ans.toString();
    }
    
    
    public String reverseLeftWords1(String s, int n) {
        return s.substring(n, s.length()) + s.substring(0, n);
    }

复制代码

提交测试:

image.png

总结

  • 循环方法的时间复杂度是 O(n), 空间复杂度是 O(1)
  • substring 系统函数的时间复杂度是 O(1), 空间复杂度是 O(1)
  • 实际题目代码提交过程中,调用系统函数 substring() 的效果更好,下面就来看一下substring()的实现。

substring() 函数分析

substring() 实现

    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }
复制代码
  • 从上述实现分析,substring 对边界进行了完备分析,返回值是对象本身,或者创建一个新的对象返回。

new String(value, beginIndex, subLen) 实现

  • 进一步分析 new String(value, beginIndex, subLen) 方法。
   public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
复制代码
  • 观察代码,实际调用的 Arrays.copyOfRange(value, offset, offset+count);

Arrays.copyOfRange() 实现

    public static char[] copyOfRange(char[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        char[] copy = new char[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }
复制代码
  • 这里是直接调用 System 函数实现
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
复制代码
  • 通过上述的代码分析,复习明确了Java String Object 是不可变的。
  • 坚持每日一题,加油!
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享