写点什么

【LeetCode】左旋转字符串 Java 题解

用户头像
HQ数字卡
关注
发布于: 2021 年 06 月 06 日

题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"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);    }
复制代码

总结

  • 循环方法的时间复杂度是 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 是不可变的。

  • 坚持每日一题,加油!

发布于: 2021 年 06 月 06 日阅读数: 9
用户头像

HQ数字卡

关注

还未添加个人签名 2019.09.29 加入

LeetCode,略懂后端的RD

评论

发布
暂无评论
【LeetCode】左旋转字符串Java题解