C#で整数配列内のすべての0(ゼロ)を配列の末尾に移動する方法
C#では、整数型の配列に含まれるすべての0を配列の末尾へ移動したいケースがあります。例えば { 0, 1, 0, 3, 12 } という配列を { 1, 3, 12, 0, 0 } のように並べ替える処理です。本記事では、効率的なアルゴリズムでこの問題を解決する MoveZeros メソッドの実装方法を解説します。
アルゴリズムの考え方
基本的なアプローチは以下の通りです。
まず MoveZeros メソッドを作成し、配列を先頭から順に走査します。走査の過程で0以外の要素を検出したら、それを配列の前方から順番に詰めていきます。次に、非ゼロ要素を格納し終えた位置から配列の末尾までを、すべて0で埋めます。これにより、元の非ゼロ要素の相対的な順序を保ちながら、すべての0を末尾に集めることができます。
なお、配列が null または空の場合は、処理を行わずにそのまま返します。最終的な結果は引数として渡された nums 配列自体に反映されます(in-place処理)。配列全体を一度だけ走査するため、時間計算量は O(N) となり、追加の配列も不要なため空間計算量は O(1) で済みます。
時間計算量 − O(N)
空間計算量 − O(1)
実装例
public class Arrays{
public void MoveZeros(int[] nums){
if (nums == null || nums.Length == 0){
return;
}
int count = 0;
for (int i = 0; i < nums.Count(); i++){
if (nums[i] != 0){
nums[count] = nums[i];
count++;
}
}
for (int i = count; i < nums.Length; i++){
nums[i] = 0;
}
}
}
static void Main(string[] args){
int[] nums = { 0, 1, 0, 3, 12 };
s.MoveZeros(nums);
foreach (var item in nums){
Console.WriteLine(item);
}
}コードの解説
最初のループでは、変数 count を「次に非ゼロ要素を書き込む位置」として使用します。nums[i] が0以外であれば、その値を nums[count] に代入し、count をインクリメントします。これにより、非ゼロ要素だけが配列の前方に圧縮されます。
2つ目のループでは、count の位置から配列の末尾までを0で埋めます。これにより、移動後の0がすべて末尾に配置されます。
出力結果
[1,3,12,0,0]
入力配列 { 0, 1, 0, 3, 12 } 内の0がすべて末尾に移動され、非ゼロ要素である 1, 3, 12 の相対的な順序は維持されたまま出力されていることが確認できます。
-
Pythonで配列にある整数の約数がすべて含まれているか確認する方法
問題概要ある配列 nums が与えられたとき、この配列が「ある整数の約数」をすべて含んでいるかどうかを判定します。たとえば、入力が nums = [1, 2, 3, 4, 6, 8, 12, 24] の場合、これらはすべて 24 の約数であるため、出力は True になります。解法のアプローチこの問題は、次の手順で解くことができます。配列内の最大値を求めます。ある整数の約数リストには必ずその整数自身が含まれるため、配列が完全な約数リストなら、最大値が対象の整数になります。1 から最大値の平方根まで順に調べ、割り切れる数 i を見つけたら、i と商 maximum // i を一時リストに追加し
-
Pythonのリスト内包表記でリスト内のすべての0を末尾に移動する方法
Pythonでは、リスト内包表記を使うことで、数値リスト内のすべての0(ゼロ)をリストの末尾に移動できます。例えば、[1, 3, 0, 4, 0, 5, 6, 0, 7] というリストの場合、処理後の結果は [1, 3, 4, 5, 6, 7, 0, 0, 0] となります。 リスト内包表記を活用すれば、この処理はわずか1行のコードで実現可能です。以下の手順に従って実装してみましょう。 処理の手順 数値のリストを初期化します。 リスト内包表記で「0以外の要素」と「0の要素」をそれぞれ抽出し、両者を連結して新しいリストを作成します。 新しいリストを出力して結果を確認します。 サンプルコード