力扣189.かいてんはいれつ
10435 ワード
力扣189.かいてんはいれつ解法一 解法二 解法三 3つの解法、解法1は簡単に考えられますが、後の2つの解法は比較的巧みで、ここで記録しておきます.
解法一
配列を1つずつ後ろに移動するたびにk%numsを移動する.length回(k%nums.lengthはnums.lengthをずらす倍数回がずらさないに相当するため)
解法二
①kビットは1単位で移動し、毎回後kビットを前kビットと交換し、前kビットが正しい位置に到達するようにする.②このとき、残りの位置は、kビットを移動する必要がある新しい配列を形成し、1を繰り返し、1の再帰に類似する.
解法三
この解法は最も巧みで、私には考えられないと思いますが...これも回転配列というタイトルに最も合っています.①配列全体を反転させる(理解:後方シフトkビットは、実は元の配列の後方kビットを一番前に移動したが、前後の順序は変わらない.直接反転した後、後方kビットを一番前に移動したが、順序が逆である.)②前k位を反転③後n-k位を反転
解法一
配列を1つずつ後ろに移動するたびにk%numsを移動する.length回(k%nums.lengthはnums.lengthをずらす倍数回がずらさないに相当するため)
// :O(kn)
// :O(1)
class Solution {
public void rotate(int[] nums, int k) {
if (nums.length == 0)
return;
int last = nums[nums.length - 1];
for (int i = 0; i < k % nums.length; i++) {
for (int j = nums.length - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = last;
last = nums[nums.length - 1];
}
}
}
解法二
①kビットは1単位で移動し、毎回後kビットを前kビットと交換し、前kビットが正しい位置に到達するようにする.②このとき、残りの位置は、kビットを移動する必要がある新しい配列を形成し、1を繰り返し、1の再帰に類似する.
// :O(n)
// :O(1)
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n;
// , k , n-k k ,
for (int start = 0; start < nums.length && k != 0; n -= k, start += k, k %= n) {
for (int i = 0; i < k; i++) {
int temp = nums[start + i];
nums[start + i] = nums[nums.length - k + i];
nums[nums.length - k + i] = temp;
}
}
}
}
解法三
この解法は最も巧みで、私には考えられないと思いますが...これも回転配列というタイトルに最も合っています.①配列全体を反転させる(理解:後方シフトkビットは、実は元の配列の後方kビットを一番前に移動したが、前後の順序は変わらない.直接反転した後、後方kビットを一番前に移動したが、順序が逆である.)②前k位を反転③後n-k位を反転
// :O(n)
// :O(1)
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n;
reverse(nums, 0, n - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, n - 1);
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start++] = nums[end];
nums[end--] = temp;
}
}