説明タイトル:
アレイ、kは非負であるk個の位置だけ右に、配列の要素を考えます。
例1:
入力:[6]、[7]及びk = 3
出力:[5,6,7,1,2,3,4]
説明:
右のステップ1の回転:[7,1 1,2,3,4,5,6]
[6,7,1,2,3,4,5]:右には2つのステップ回転
右ステップ3に回転を[5,6,7,1,2,3 、4]
出典:滞在ボタン(LeetCode)
C / C ++
- まず試してみてください。
思考:Oの時間複雑度(N)は、追加のメモリ空間を必要とする良い方法ではない:
1配列の同じ長さの作成
2、インデックスは、アレイ内の各配列値の元のサイズの移動後に元のサイズよりも大きいか否かに応じてこれらは、空の配列に対応する位置に配置され
NUMSは、[I] / ARR [I +(K%のnumsSize) - numsSizeは] = [I +(K numsSizeの%)] ARR NUMS [I]を=;
3、新しい配列をコピーします。元の配列に、プログラムが終了しました
void rotate(int* nums, int numsSize, int k) {
// int arr[numsSize];
int * arr;
arr = (int*)malloc(sizeof(int) * numsSize);
for (int i = 0; i < numsSize; i++) {
if ((i + (k % numsSize)) < numsSize) {
arr[i + (k % numsSize)] = nums[i];
}
else {
arr[i + (k % numsSize) - numsSize] = nums[i];
}
}
for (int i = 0; i < numsSize; i++) {
nums[i] = arr[i];
}
}
結果:
- リファレンスを変更した後:
新しいアイデア:3つの回転
三つの回転
観察が利用できる:配列フリップ、そこヘッダ要素の残りの部分はテール要素になるように移動した後に後続の要素は、ヘッドのアレイに移動する(K%のサイズ)である
。従って、我々は、最初の配列全体を反転、及びヘッド(K%の1)番目のフリップフロッヘッダ要素、最後に残りの尾反転素子(3つの回転)
C
void reverse(int *a, int l, int h)
{
for(int i = 0; i < (h - l + 1) / 2; i++){
int t = a[l + i];
a[l + i] = a[h - i];
a[h - i] = t;
}
}
void rotate(int* nums, int numsSize, int k){
if(!nums || numsSize == 0)
return;
k = k % numsSize;
reverse(nums, 0, numsSize - 1 - k);
reverse(nums, numsSize - k, numsSize - 1);
reverse(nums, 0, numsSize - 1);
}
結果:
C ++
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int len=nums.size();
reverse(nums.begin(), nums.end() - k%len); //reverse翻转的是[begin,end)区间
reverse(nums.end()- k%len,nums.end());
reverse(nums.begin(),nums.end());
}
};
結果:
3回転を達成するためのPythonコード
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n=len(nums)
k=k%n
def swap(l,r):
while(l<r):
nums[l],nums[r]=nums[r],nums[l]
l=l+1
r=r-1
swap(0,n-k-1)
swap(n-k,n-1)
swap(0,n-1)
3つの回転の実現を達成するためのJavaコード *
public class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}
要約:
ローカル関数の配列を作成1.、直接使用することができない(INT ARR [N])、ローカル変数から作成されているようなアレイを作成するために、それが通過することができず、むしろその((INT *)はmalloc(はsizeof()) )動的に作成。
図2に示すように、フリップインサイチュ法の配列:三エンドレスロータリー回転法