LeetCode – 數組的旋轉總結
1. 數組的旋轉總結
數組的旋轉指的是將數組的最後若干個數提前到數組前面,數組的翻轉指的是將數組的順序顛倒。旋轉可以通過多次翻轉實現。
數組的翻轉很簡單,通過雙指針來實現:交換數組的第一個數和最後一個數,交換第二個數和倒數第二個數,一直到數組中間即可。
2. 題目記錄
189. 輪轉數組
分析題意
給你一個數組,將數組中的元素向右輪轉 k
**個位置,其中 k
**是非負數。
思路分析
其實題目就是一個數組旋轉問題,我們可以通過圖片來分析一下:

將上面這個數組向右輪轉3個位置,其實就是:將數組的後3個元素旋轉到數組前面,即:數組的旋轉。前面我們講到:數組的旋轉可以通過多次數組翻轉來實現:

我們首先對整個數組進行翻轉,然後對每一個子數組進行翻轉,即:數組的旋轉通過三次數組的翻轉來實現。
class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
// 整個數組進行翻轉
reverse(nums, 0, nums.length - 1);
// 前k個元素進行翻轉
reverse(nums, 0, k - 1);
// 剩餘元素進行翻轉
reverse(nums, k, nums.length - 1);
}
void reverse(int[] nums, int left, int right){
int temp = 0;
while(left < right){
temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left ++;
right --;
}
}
}
複雜度分析
時間複雜度:\(O(n)\)
空間複雜度:\(O(1)\)
396. 旋轉函數
分析題意
看到題目似乎我們需要模擬旋轉操作,然後求出每次旋轉之後的總和,並所有旋轉總和中取最大值。
但其實只求最大值的話,我們無需進行模擬。讓我們來看看不同旋轉操作之間的規律性:
a = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6)
b = (1 * 4) + (2 * 3) + (3 * 2) + (0 * 6)
c = (2 * 4) + (3 * 3) + (0 * 2) + (1 * 6)
d = (3 * 4) + (0 * 3) + (1 * 2) + (2 * 6)
從上面我們可以分析一下a、b、c和d之間的關係:
b = a + 4 + 3 + 2 + 6 - 4 * 6
c = b + 4 + 3 + 2 + 6 - 4 * 2
d = c + 4 + 3 + 2 + 1 - 4 * 3
每次都等於上次的和加上數組總和減去當前遍歷到的元素的n
倍。
思路分析
class Solution {
public int maxRotateFunction(int[] nums) {
int sum = 0;
int ans = 0;
for(int i = 0; i < nums.length; i++){
ans = ans + i * nums[i];
sum += nums[i];
}
int pre = ans;
for(int i = nums.length - 1; i >= 0; i--){
pre = pre + sum - nums.length * nums[i];
ans = Math.max(ans, pre);
}
return ans;
}
}
複雜度分析
時間複雜度:\(O(n)\)
空間複雜度:\(O(1)\)