【百日算法计划】:每日一题,见证成长(001)
题目
左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。
请定义一个函数实现字符串左旋转操作的功能。
比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"
示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”
思路 1
开辟一个和原数组一样大小的新数组,把原数组的数据拷贝到新数组,时间复杂度O(n),空间复杂度O(n)。
public static String reverseLeftWords1(String s,int n){
/*
* 若原数据长度为k=s.length
* 1.申请一个和原数组长度一样的新数组 nChar
* 2.拷贝[n~k-1]的数据到新数组
* 3.拷贝[0-n-1]的数据到新数组
* 4.返回新数组
*/
int k = s.length();
char[] nChar = new char[k]; //申请一个新数组
int m = 0;
for (int i = n; i < k; i++) {
nChar[m] = s.charAt(i);
m++;
}
for (int i = 0; i < n; i++) {
nChar[m] = s.charAt(i);
m++;
}
return new String(nChar);
}
思路2
开辟一个长度为K的新数组,把需要搬移的数据放到新数组,同时原数组数据前移,最后把新数组的数据拷贝到原数组的后面,时间复杂度O(n) 空间复杂度O(k)。
public static String reverseLeftWords3(String s,int n){
/*
* 1.申请一个长度为n的新数组 nChar
* 2.拷贝[0~n-1]的数据到新数组
* 3.原数组往前移动数据
* 4.新数组数据拷贝到原数组的后面
*/
char[] oChar = s.toCharArray();
char[] nChar = new char[n]; //申请一个长度为n新数组
for (int i = 0; i < n; i++) {
nChar[i] = oChar[i]; //拷贝要翻转的数据到新数组
}
for (int i = n; i < oChar.length; i++) { //老数组的元素向前移动
oChar[i - n] = oChar[i];
}
for (int i = 0; i < nChar.length; i++) { //把新数组元素拷贝到老数组的末尾
oChar[s.length() - n + i] = nChar[i];
}
return new String(oChar);
}
思路3
申请一个长度为1的新数组,把需要搬移的数据放到新数组,同时原数组数据前移,循环k次
时间复杂度O(k*n) 空间复杂度O(1),如果k非常接近n,那么时间复杂度就接近O(n的平方)。
public static String reverseLeftWords2(String s, int n) {
char[] chars = s.toCharArray();
for (int i = 0; i < n; ++i) {
char tmp = chars[0]; //先拿到需要挪动的字符,临时保存,每次都拿第一个元素(注意 不是chars[i])
for (int j = 1; j < s.length(); ++j) { //向前移动一位
chars[j - 1] = chars[j];
}
chars[s.length() - 1] = tmp;//放到末尾
}
return new String(chars);
}