LeetCode189。回転配列

189.回転アレイ

トピックの説明

配列が与えられたら、配列の要素を右にk位置回転します。ここで、kは非負の数です。OJリンク

你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

1.例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.例2

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1: [99,-1,-100,3]
向右轮转 2: [3,99,-1,-100]

問題解決のアイデア

  • アルゴリズムのスペースを複雑にするために、O(1)、その場での回転、つまり追加の配列を作成することはできません。

例として例1を取り上げます。作る用三次逆转法,让数组旋转k次

  1. まず、全体的な逆転は次のようになります(7,6,5,4,3,2,1)

  2. サブ配列[0、k-1]を反転すると次のようになります(5,6,7,4,3,2,1)

  3. サブ配列[k、numsSize-1]を反転すると次のようになります(5,6,7,1,2,3,4)

1.最初の全体的な逆転

それぞれ頭と尾を指すように2つのポインター変数を設定します。begin <endの場合、2つの位置の値を交換します。緑の数字はスワップポジションです。ここに画像の説明を挿入

2.逆サブアレイ[0、k-1]

ここに画像の説明を挿入
ここに画像の説明を挿入ここに画像の説明を挿入

3.サブアレイを逆にします[k、numsSize-1]

ここでは繰り返されませんが
、上記の2つのステップの考え方は同じです。
これでアレイの回転が完了します。

エラーを起こしやすい

回転する必要のある数値kが配列numsSizeの長さよりも大きい場合はどうなりますか?
kが10の場合、この問題の結果は何ですか?
もしも右旋10个数,那么先旋7个后将又回到了原来的样子。 然后再旋3个的话那么将和本题的旋3个一模一样。

  • この質問の本質は、回転配列と呼ばれるタイトルです。案の定天道好轮回7回回転し、開始点に戻ります。7の倍数が元の場所に戻る限り、14回、21回回転します。
  • したがって、kの倍数であるかどうかの判断コードをタイトルに追加する必要があります。
	if (k > numsSize)
	{
    
    
		k %= numsSize;
	}

コード

このコードは主な機能を果たします。LeetCodeトピックは、メイン関数のないインターフェイスタイプです。
3回回転させる必要があるからです。したがって、簡単に再利用できるように、whileループを関数として記述します。

 LeetCode189. 轮转数组
#include<stdio.h>

void rotate1(int* begin, int* end)
{
    
    
	while (begin < end)
	{
    
    
		int t = 0;
		t = *begin;
		*begin = *end;
		*end = t;
		++begin;
		--end;
	}
}
void rotate(int* nums, int numsSize, int k) 
{
    
    
	//假如右旋10个数,先旋7个后又回到了原来的样子。然后再旋3次的话和本题再旋3次一模一样。
	if (k > numsSize)
	{
    
    
		k %= numsSize;
	}
	int* begin = nums;
	int* end = nums + numsSize - 1;
	rotate1(begin, end);
	rotate1(begin, begin+k-1);
	rotate1(begin + k, end);

}
int main()
{
    
    
	int nums[] = {
    
     1,2,3,4,5,6,7 };
	int sz = sizeof(nums) / sizeof(nums[0]);
	rotate(nums, sz, 3);

	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ", nums[i]);
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/qq2466200050/article/details/123481769