📅  最后修改于: 2023-12-03 14:43:03.395000             🧑  作者: Mango
在某些情况下,需要将数组向右旋转K次,然后输出旋转后的数组。例如,如果数组为[1,2,3,4,5],K=3,那么数组的旋转结果将是[3,4,5,1,2]。
如何在Java程序中实现这个功能呢?本文将介绍两种方法。
暴力解法是常见的数组旋转方法。其基本思想是:将数组末尾的K个元素移到数组开头。这个过程可以反复多次直到达到K次旋转后。
/**
* 将数组向右旋转k次,然后输出旋转后的数组
*
* @param nums 数组
* @param k 右旋转次数
*/
public void rotate(int[] nums, int k) {
int len = nums.length;
k = k % len;
for (int i = 0; i < k; i++) {
int last = nums[len - 1];
for (int j = len - 1; j > 0; j--)
nums[j] = nums[j - 1];
nums[0] = last;
}
System.out.println(Arrays.toString(nums));
}
在这个代码片段中,我们首先用模运算确定了实际需要执行的旋转次数。然后我们使用两层嵌套的循环,以将数组旋转K次。在内层循环中,我们遍历数组元素,将每个元素移动到它的前一个位置。最后,我们将原数组末尾的元素放入索引为0的位置,即完成了一次数组的旋转。重复K次后,我们就得到了旋转后的数组并打印出来。
这个方法的时间复杂度是O(n*k),空间复杂度是O(1)。
使用反转法可以使解法更优,时间复杂度为O(n),空间复杂度也为O(1)。
思路如下:
反转数组的代码如下:
/**
* 反转数组
*
* @param nums 数组
* @param start 起始位置
* @param end 结束位置
*/
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
反转前K个元素的代码如下:
/**
* 将数组向右旋转k次,然后输出旋转后的数组
*
* @param nums 数组
* @param k 右旋转次数
*/
public void rotate2(int[] nums, int k) {
int len = nums.length;
k = k % len;
reverse(nums, 0, len - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, len - 1);
System.out.println(Arrays.toString(nums));
}
我们首先使用模运算来确定实际需要执行的旋转次数。接着我们反转整个数组,这样就将数组末尾的K个元素移到了数组开头。然后我们再反转前K个元素,这样就将移动的K个元素移回了原来的位置。最后,我们再反转后面的元素,保持它们的相对位置不变。这样我们就完成了K次旋转,并打印出了旋转后的数组。
两种方法都可以实现数组旋转。暴力解法可能会超过时间限制(LeetCode测试数据限制为1秒钟),但是它比反转法更容易理解。反转法的时间复杂度更优,但是需要理解反转数组的思路,掌握好基础的翻转技巧。
如果需要处理大量数据请使用反转法旋转。如果时间限制比较宽裕,建议先使用暴力解法实现,加深对数组旋转的理解和掌握翻转技巧。