lt.189. 轮转数组
[案例需求]
[思路分析]
[代码实现一, 笨方法(新数组暂存, 复制到旧数组)]
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
int[] newArr = new int[n];
for (int i = 0; i < n; ++i) {
newArr[(i + k) % n] = nums[i];
}
System.arraycopy(newArr, 0, nums, 0, n);
}
}
[代码实现二, 三次旋转方法]
左旋和右旋, 其实都可以用三次旋转方法去解决, 在细节上会有轻微的差别;
1. 左旋转
- 整个字符串向左移动k位, 右边空出的位置由左边0~k去补充上;
第一次旋转: 旋转整个数组或字符串, reverse(nums, 0, len - 1);
第二次旋转: 旋转(0 ~ k - 1), reverse(nums, 0, k - 1)
第三次旋转: 剩余的是后半段(k ~ len - 1), reverse(nums, k, len - 1)
所以, 本题(右旋数组) 的代码实现如下:
class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
int rotateCount = k % len;
reverse(nums, 0, len - 1);
reverse(nums, 0, rotateCount - 1);
reverse(nums, rotateCount, len - 1);
}
public void reverse(int[] nums, int left, int right){
while(left <= right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
++left;
--right;
}
}
}
剑指 Offer 58 - II. 左旋转字符串(左旋字符串)
案例说明
2. 右旋转
- 整个字符串向右移动k位, 左边空出的位置由左边0~k去补充上;
第一次旋转: 旋转整个数组或字符串, reverse(nums, 0, len - 1);
第二次旋转: 旋转0~len - k位置, reverse(nums, 0, len - k - 1)
第三次旋转: 剩余的是后半段, reverse(nums, len - k, len - 1)
class Solution {
public String reverseLeftWords(String s, int k) {
//substring(from, to)
//substring(from, to) substring(fron, to)
//return new String(s.substring(k, s.length())) + new String(s.substring(0, k));
char[] chars = s.toCharArray();
int len = chars.length;
reverse(chars, 0, len - 1);
reverse(chars, 0, len - k - 1);
reverse(chars, len - k, len - 1);
return String.valueOf(chars);
}
public void reverse(char[] chars, int left, int right){
while(left < right){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
++left;
--right;
}
}
}