题目
方法一-字符串切片
算法思路
直接使用字符串切片函数获得 s[0 : n - 1] 和 s[n : ]然后将两者拼接起来
具体代码
class Solution {
public String reverseLeftWords(String s, int n) {
String res1 = s.substring(n);
String res2 = s.substring(0, n);
return res1.concat(res2);
}
}
复杂度分析
- 时间复杂度:
O
(
n
)
O(n)
O(n),n 为字符串长度。字符串切片函数
substring()
为线性时间复杂度。 - 空间复杂度: O ( n ) O(n) O(n),两个切片的长度之和为 n
方法二-列表遍历拼接
算法思路
利用StringBuilder
,先添加第 n+1 位至末位的字符,再添加首位至第 n 位的字符,最后转化为字符串并返回。
具体代码
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i = n; i < s.length(); i++){
res.append(s.charAt(i));
}
for(int i = 0; i < n; i++){
res.append(s.charAt(i));
}
return res.toString();
}
}
取余运算简化代码:
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i = n; i < n + s.length(); i++){
res.append(s.charAt(i % s.length()));
}
return res.toString();
}
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
方法三-字符串遍历拼接
算法思路
与方法二思路相同,只是 使用字符串代替列表。
具体代码
class Solution {
public String reverseLeftWords(String s, int n) {
String res = "";
for(int i = n; i < s.length(); i++){
res += s.charAt(i);
}
for(int i = 0; i < n; i++){
res += s.charAt(i);
}
return res;
}
}
取余运算简化代码:
class Solution {
public String reverseLeftWords(String s, int n) {
String res = "";
for(int i = n; i < n + s.length(); i++){
res += s.charAt(i % s.length());
}
return res;
}
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度:
O
(
n
)
O(n)
O(n),新建长度为 n 的
res
需要使用前一个长度为 n - 1 的res
,假设循环过程中内存会被及时回收,那么内存中至少同时存在长度为 n 和 n - 1 的两个字符串,故至少使用 O ( n ) O(n) O(n) 的额外空间。
需要注意的是,Java中字符串是 不可变对象,因此每一次拼接字符都要新建一个字符串,所以整个过程一共要申请 n 次内存,数据量大时效率较低。