C++で配列が「ソート済みかつ回転」されているか判定する方法
整数の配列が与えられたとき、その配列が昇順にソートされた状態から、ある位置で回転(ローテーション)されているかどうかを判定するのが本記事のテーマです。
問題の例
入力1:
N = [7, 8, 9, 4, 5, 6]
出力:
True
解説: 配列は昇順に並んでおり、3番目の位置を境に要素が回転しているため、この場合は True を返します。
入力2:
N = [1, 5, 7, 6, 2, 3]
出力:
False
解説: 配列は昇順にも並んでおらず、特定の位置での回転も行われていないため、出力は False になります。
解き方のアプローチ
配列の要素は昇順に並んでいるか、あるいはバラバラの順序になっています。もし配列が「ソート済みかつ回転済み」であれば、N[i] > N[i+1] を満たす箇所は必ず1つだけ存在します。それは回転の境界となる部分です。
そこで、配列内のすべての隣接ペアについてこの条件をチェックし、条件を満たす箇所の数をカウントします。カウントが1以下であれば True、そうでなければ False を返せばよいのです。
アルゴリズムの手順
- 配列の要素を入力として受け取ります。
- ブール関数
checkSortedandRotated(int *arr, int n)は、配列とそのサイズを引数に取り、配列がソート済みかつ回転済みであれば true を、そうでなければ false を返します。 - 配列全体を走査し、
arr[i] > arr[(i + 1) % n]を満たす要素の数をカウントします。剰余演算% nを使うことで、末尾と先頭の比較(回転の境界)も正しく処理できます。 - カウントが「1」以下であれば true を返し、それ以外の場合は false を返します。
- 結果を出力します。
C++での実装例
#include <bits/stdc++.h>
using namespace std;
bool checkSortedandRotated(int * arr, int n) {
int count = 0;
for (int i = 0; i < n; i++) {
if (arr[i] > arr[(i + 1) % n])
count++;
}
return (count <= 1);
}
int main() {
int arr[] = {5,6,7,1,2,3,4};
int n = sizeof(arr) / sizeof(int);
if (checkSortedandRotated(arr, n)) {
cout << "True" << endl;
} else {
cout << "False" << endl;
}
return 0;
}
上記のコードを実行すると、次の出力が得られます。
出力
True
与えられた配列 [5, 6, 7, 1, 2, 3, 4] は、3番目の位置から回転されたソート済み配列であるため、この場合の出力は「True」となります。
計算量
このアルゴリズムは配列を一度だけ走査するため、時間計算量は O(n) です。また、追加のメモリを必要としないため、空間計算量は O(1) となり、非常に効率的な手法と言えます。
-
Pythonで配列が「ソート済み+回転」状態かどうかを判定するプログラム
問題の概要nums という配列が与えられたとき、その配列が「もともと非減少順(昇順)にソートされていたものを、何度か(0回でも可)回転させた結果」になっているかどうかを判定します。配列には重複した要素が含まれている場合もあります。たとえば、入力が nums = [12,15,2,5,6,9] の場合、出力は True になります。これは、ソート済みの配列 [2,5,6,9,12,15] を右に2回転させると [12,15,2,5,6,9] になるためです。解決のアプローチこの問題は、次の手順で解くことができます。変数 j を 0 に初期化します。j が「配列の長さ − 1」未満であり、かつ n
-
Pythonで配列が「ソート済みかつ回転」しているかを判定する方法
問題の概要 n個の一意な値で構成される配列があるとします。この配列が「昇順にソートされた状態から回転した配列」であるかどうかを判定してください。ただし、少なくとも1回の回転が必要なため、完全にソートされただけの配列は「ソートかつ回転」とはみなされません。 たとえば、入力が nums = [4,5,6,8,1,3] の場合、出力は True になります。この配列を2回回転すると [1, 3, 4, 5, 6, 8] という昇順の配列になるためです。 アルゴリズムの考え方 回転されたソート配列の最大の特徴は、最小値を境に配列が2つの昇順部分に分かれることです。この性質を利用して、以下の手順で判定