题干:
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
解题:
方法一:
借助临时数组实现。临时数组存储和原始数组相同的数据,作为备份。根据后移距离依次计算出元素的目标位置,在目标位置上通过临时数组进行填值。
代码示例:
java版本:
public static void rotate(int[] nums, int k) {
if (k == 0) { // 为0的快速返回
return;
}
k = k % nums.length; // 获取实际后移步长,(因为等于数组长度的部分还会回到当前位置,所以需要求余数)
int[] tempArray = Arrays.copyOfRange(nums, 0, nums.length); // 临时数组
for (int i = 0; i < nums.length; i++) {
if (i < k) { // 目标位置之前的元素,元素会从队尾环形回到头部
nums[i] = tempArray[i - k + nums.length];
} else { // 目标位置之后的元素,从头部偏移直接获取
nums[i] = tempArray[i - k];
}
}
}
C版本:
void rotate(int* nums, int numsSize, int k) {
if(numsSize == 0){
return;
}
int tempArr[numsSize];
for(int i =0; i<numsSize;i++){
tempArr[i] = nums[i];
}
k = k%numsSize;
for(int i =0; i<numsSize;i++){
if(i<k){
nums[i] = tempArr[i-k+numsSize];
} else{
nums[i] = tempArr[i-k];
}
}
}
方法二:
通过数组反转实现。数组向后移动k个,那么必定会有k个元素从队尾会到对头。
将数组整体反转后,对头前k个元素一定是目标转移的元素,不过顺序是反着的。同理之后的元素也是一样,范围正确,顺序相反。
所以在对前k部分反转。后面部分的数组反转可以得到结果。
代码示例:
java版本:
public static void rotate(int[] nums, int k) {
if (k == 0) {
return;
}
k = k % nums.length;
reviseArray(nums, 0, nums.length - 1); // 整体反转
reviseArray(nums, 0, k - 1); // 反转后的前k个元素反转
reviseArray(nums, k, nums.length - 1); // 反转后的,k之后的部分反转
}
// 数组反转
private static void reviseArray(int[] nums, int left, int right) {
if (left >= right) {
return;
}
while (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
C版本:
// 元素交换
void swap(int* a, int* b) {
int t = *a;
*a = *b, *b = t;
}
// 数组反转
void reverse(int* nums, int start, int end) {
while (start < end) {
swap(&nums[start], &nums[end]);
start += 1;
end -= 1;
}
}
void rotate(int* nums, int numsSize, int k) {
k %= numsSize;
reverse(nums, 0, numsSize - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, numsSize - 1);
}
逆风翻盘,Dare To Be!!!