トピックステートメント:
偶数 n が与えられると、長さ n のパーマ perm が存在することがわかります。ここで、perm[i] == i (添え字は 0 から数え始めます)。
1 つのステップで、各 i に対して新しい配列 arr を作成します。
i % 2 == 0 の場合、arr[i] = perm[i / 2]
i % 2 == 1 の場合、arr[i] = perm[n / 2 + (i - 1) / 2
] arr パーマに配属されました。
パーマを元の順列に戻すために必要な最小手順は何ですか? ゼロ以外の最小の操作ステップ数を返します。
例 1:
入力: n = 2
出力: 1
説明: 最初は perm = [0,1]
ステップ 1 の後、perm = [0,1]
したがって、必要なステップは 1 つだけです
例 2:
入力: n = 4
出力: 2
説明: 最初は perm = [0,1,2,3]
ステップ 1 の演算後、perm = [0,2,1,3]
ステップ 2 の演算後、perm = [0 ,1 ,2,3]
したがって、必要な手順は 2 つだけです
例 3:
入力: n = 6
出力: 4
ヒント:
2 <= n <= 1000
n は偶数です
問題解決のアイデア:
n の最大値の範囲が 1000 のみであることから、この問題には多くの解決策があります。
1 つは数学的な解決策で、問題を解決するためのコードのみが以下に示されているため、これ以上は説明しません。
もう 1 つは単純なシミュレーション シチュエーションで、元の配列パーマと同じになるまですべてのシチュエーションをシミュレートし、シミュレーション シチュエーションの数を計算します。元の配列を新しい配列に割り当てる必要があることに注意してください。これは、元の配列と新しい配列が同じかどうかを比較し、同じ場合に返すために使用されます。
問題解決コード (数学):
class Solution {
public:
int reinitializePermutation(int n) {
if (n == 2) {
return 1;
}
int step = 1, pow2 = 2;
while (pow2 != 1) {
step++;
pow2 = pow2 * 2 % (n - 1);
}
return step;
}
};
問題解決コード (シミュレーション):
class Solution {
public:
int reinitializePermutation(int n) {
vector<int>perm(n,0);
vector<int>arr(n,0);
int cnt=0;
for(int i=0;i<n;i++)
{
perm[i]=i;
}
vector<int>path;
path.assign(perm.begin(),perm.end());
while(arr!=path)
{
for(int i=0;i<n;i++)
{
if(i%2==0)
{
arr[i]=perm[i/2];
}
else
{
arr[i]=perm[n/2+(i-1)/2];
}
}
cnt++;
perm.assign(arr.begin(),arr.end());
}
return cnt;
}
};
この問題は簡単な問題ですが、nを1e9増やすのは難しい気がします!!!