每日一例 | 对java来说这是个简单问题:字符串左旋

云中志

共 5241字,需浏览 11分钟

 ·

2021-05-19 07:16


题目描述

题目来源:力扣(LeetCode

链接:https://leetcode-cn.com/problems/roman-to-integer/

难度:简单

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

示例 1:

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

示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"

限制:

1 <= k < s.length <= 10000

提交记录

看完这个题目,我觉得很简单,提交完,我也觉得很简单:

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n) + s.substring(0, n);
    }
}

但是,看完提交的数据,我觉得问题并没有这么简单:

运行时间上没有任何问题,但是内存消耗上,并不是特别优秀,我想看下有没有双100的揭发,毕竟这么简单的一个问题,不再多研究下,都对不起出题人,我们先看编译后的代码:

class Solution {
    Solution() {
    }

    public String reverseLeftWords(String s, int n) {
        return s.substring(n) + s.substring(0, n);
    }
}

确实和源代码一致,没有什么可以优化的点,那我们换种方式重新实现,然后看下提交记录。

stringBuilder

class Solution {
    public String reverseLeftWords(String s, int n) {
        return new StringBuilder(s.substring(n)).append(s.substring(0, n)).toString();
    }
}

换成StringBuilder字符串拼接,发现没啥用,内存反而上去了:

数组

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        return new String(Arrays.copyOfRange(chars, n, s.length())) + new String(Arrays.copyOfRange(chars, 0, n));
    }
}

换成数组,内存消耗上去了,运行时间又下来了:

然后我又换了一种数组拷贝的方式,但是执行时间太长了:

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        char[] targetChars = new char[chars.length];
        for (int i = 0; i < chars.length; i++) {
            if (i < n && (n + i) < chars.length) {
               targetChars[i] = chars[n + i];
            } else if (i >= chars.length - n) {
                targetChars[i] = chars[i - (chars.length - n)];
            } else {
                 targetChars[i] = chars[i + n];
            }
        }
        return new String(targetChars);
    }
}

执行时间太长了:

提交之后,我发现第一个if和最后面的else语句其实可以合并,然后就便成了这样:

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] chars = s.toCharArray();
        char[] targetChars = new char[chars.length];
        for (int i = 0; i < chars.length; i++) {
            if (i >= chars.length - n) {
                targetChars[i] = chars[i - (chars.length - n)];
            } else {
                 targetChars[i] = chars[i + n];
            }
        }
        return new String(targetChars);
    }
}

再次提交,性能确实比刚才好了,而且内存方面更优秀了,但是时间上确实还不太行:

好吧,数组这块已经算是到极限了,应为要循环遍历数组,所以时间上肯定是不行的,字符串越多,时间会越长,也就是时间复杂度过高。

好吧,我放弃了,今天就到这里吧,有事要溜了……

总结

简单来说,通过今天的示例,我发现想要优化内存方面的性能,有数组是更好的选择,但如果要优化时间,要避免时间复杂度过高的操作,比如循环、过多的条件语句。

- END -


浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报