C++で配列をジグザグ順に並べ替えるアルゴリズムを解説
はじめに
このチュートリアルでは、配列をジグザグ形式(zig-zag fashion)に変換するC++プログラムについて解説します。
ここでは、重複のない要素からなる配列が与えられます。私たちのタスクは、隣接する要素どうしが「小さい → 大きい → 小さい → 大きい…」と交互になるように、配列の要素を並べ替えることです。
例えば、入力配列が {4, 3, 7, 8, 6, 2, 1} の場合、期待される出力は {3, 7, 4, 8, 2, 6, 1} となります。この結果では arr[0] < arr[1] > arr[2] < arr[3] … という大小関係が交互に成り立っています。
アルゴリズムの考え方
この問題は、ブール型のフラグを1つ用意するだけで、追加の配列を使わずに線形時間で解くことができます。手順は以下の通りです。
- フラグ
flagをtrueで初期化します。trueは「現在の要素が次の要素以下であるべき」ことを意味します。 - 配列を先頭から順に走査し、
flagがtrueのときにarr[i] > arr[i+1]であれば2つの要素を交換します。 flagがfalseのときは、arr[i] < arr[i+1]であれば交換します。- 各反復の最後で
flagを反転させ、大小の関係を交互に切り替えます。
C++による実装例
#include <iostream>
using namespace std;
// ジグザグ形式への変換
void convert_zigzag(int arr[], int n) {
// flagは大小関係を表す(trueなら「小さい」が先)
bool flag = true;
for (int i = 0; i <= n - 2; i++) {
if (flag) {
// 現在の要素が次より大きければ交換
if (arr[i] > arr[i + 1])
swap(arr[i], arr[i + 1]);
} else {
// 現在の要素が次より小さければ交換
if (arr[i] < arr[i + 1])
swap(arr[i], arr[i + 1]);
}
flag = !flag;
}
}
int main() {
int arr[] = {4, 3, 7, 8, 6, 2, 1};
int n = sizeof(arr) / sizeof(arr[0]);
convert_zigzag(arr, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
実行結果
3 7 4 8 2 6 1
処理の流れを確認しよう
入力 {4, 3, 7, 8, 6, 2, 1} を例に、各ステップでの動きを見てみましょう。
- i = 0(flag = true): 4 > 3 なので交換 →
{3, 4, 7, 8, 6, 2, 1} - i = 1(flag = false): 4 < 7 なのでそのまま
- i = 2(flag = true): 7 > 4…ではなく 7 < 8 なのでそのまま(7 > 8 は偽)→ 実際には 7 > 8 が成立しないため無交換
- i = 3(flag = false): 8 > 6 なので条件
arr[i] < arr[i+1]は不成立、しかし 8 > 6 のため交換 →{3, 4, 7, 6, 8, 2, 1} - i = 4(flag = true): 8 > 2 なので交換 →
{3, 4, 7, 6, 2, 8, 1} - i = 5(flag = false): 8 > 1 なので交換 →
{3, 4, 7, 6, 2, 1, 8}…最終的に3 7 4 8 2 6 1となります。
ポイントは、各位置で必要な場合だけ隣接要素を交換すればよいことです。すでに条件を満たしているペアには触れないため、全体として最小限の操作で済みます。
計算量
- 時間計算量: O(n) — 配列を一度だけ走査すればよいため非常に高速です。
- 空間計算量: O(1) — フラグ1つだけで処理でき、追加のメモリは不要です。
まとめ
ジグザグへの並べ替えは、ソートのような複雑な処理を必要とせず、ブールフラグによる隣接要素の交換だけで実現できます。O(n) 時間・O(1) 空間という優れた効率を持つため、面接や競技プログラミングでも頻出の定番アルゴリズムです。ぜひ自分のコードにも取り入れてみてください。
-
C#でタプルを配列に変換する方法
C#では、Tupleクラスを使って複数の値をひとつのオブジェクトとして扱うことができます。ここでは、作成したタプルの各要素(Item1、Item2)を取り出し、int型の配列へ変換する基本的な手順を紹介します。1. タプルを作成するまず、Tuple.Createメソッドを使用して、2つのint型の値を持つタプルを生成します。Tuple<int, int> t = Tuple.Create(99, 53);2. タプルを配列に変換する次に、タプルのプロパティであるItem1とItem2を参照して、新しいint型配列の要素として格納します。int[] arr = new int[] {
-
【C#入門】2次元配列を1次元配列に変換する方法をわかりやすく解説
C#で2次元配列を1次元配列に変換するには?プログラミングでは、2次元配列のデータを1次元配列として扱いたい場面がよくあります。C#では、ネストしたforループとカウンタ変数を組み合わせることで、2次元配列の全要素を1次元配列へ簡単にコピーできます。本記事では、その具体的な手順とサンプルコードを解説します。手順1:2次元配列と1次元配列を宣言するまず、変換元となる2次元配列と、変換先となる1次元配列を用意します。int[] a = new int[2, 2] {{1,2}, {3,4}}; int[] b = new int[4];ここでのポイントは、1次元配列のサイズを「行数 × 列数」で指