-
Pythonで連結リストをk個ずつのグループに分けて反転させる方法
片方向連結リストと整数 k が与えられたとき、リストを先頭から k 個ずつの連続するグループに分割し、それぞれのグループ内でノードの並びを反転させる問題を考えます。たとえば、入力が List = [1,2,3,4,5,6,7,8,9,10]、k = 3 の場合、出力は [3, 2, 1, 6, 5, 4, 9, 8, 7, 10] となります。3個ごとに区切られた各グループが逆順になっており、余った要素(この例では最後の 10)は元の順序のまま保持される点に注目してください。アルゴリズムの流れこの問題を解くには、次の手順に従います。値 0 を持つダミーノード tmp を作成し、tmp の次に元
-
Pythonで全員を救出するために必要なロケット船の最小数を求めるプログラム
問題の概要 人々の体重を表す数値のリスト weights と、1台のロケット船に許容される重量制限を示す値 limit が与えられているとします。各ロケット船には最大2人までしか乗せることができません。このとき、全員を惑星へ救出するために必要なロケット船の最小数を求めるのが課題です。 たとえば、入力が weights = [300, 400, 300]、limit = 600 の場合、出力は 2 になります。これは、体重300の2人を1台目のロケット船に乗せ、体重400の人を2台目のロケット船で運ぶためです。 解決のためのステップ この問題は「貪欲法(グリーディ法)」を用いることで効率的に解
-
Pythonで解く:訪問済みマスをスキップして移動するロボットが目標座標に到達するかを判定するプログラム
問題の概要 直交座標平面上の原点 (0, 0) にロボットが置かれているとします。このロボットには、N(北)、S(南)、W(西)、E(東)の4種類の移動命令からなるリストが与えられます。ただし、次の特殊なルールがあります。すでに訪れたことのある地点に到達した場合、ロボットは未訪問の地点に到達するまで同じ方向へ移動し続けるというものです。 このルールのもとですべての移動を実行したあと、ロボットが指定された座標 (x, y) に到達しているかどうかを判定するのが、この記事で扱う課題です。 入力例と動作の確認 たとえば、次のような入力を考えてみましょう。 moves = [N, N, E, N,
-
Pythonで正方行列を反時計回りに90度回転させる方法
正方行列が与えられたとき、それを反時計回りに90度回転させることを考えてみましょう。例として、次のような3×3の行列があるとします。147258369これを反時計回りに90度回転させると、出力は次のようになります。789456123解決のための手順この問題は、「各行の反転」と「転置(行と列の入れ替え)」という2つの基本的な操作を組み合わせることで解くことができます。具体的な手順は以下の通りです。行列が空である場合は、空のリストを返しますn := 行列の行数とします行列の各行に対して、その行を反転(リバース)しますi を 0 から n-1 まで繰り返します:j を 0 から i-1 まで繰り返し
-
Pythonで同時に進行しているタスクの数を求めるプログラム
問題の概要 各要素が [start, end) の形式で表される区間のリスト intervals と、文字列のリスト types が与えられているとします。ある添字 i について、intervals[i] は「誰かが types[i] の種類の作業を時間帯 [start, end) に行っていた」ことを示します。なお、同じ種類の作業に対応する2つの区間が重なることや接触することはありません。 このとき、[start, end, num_types] という形式の項目からなるソート済みのマージ済みリストを作成してください。各項目は「start から end までの期間に、num_types 個の
-
Pythonで敵同士が同じグループに入らないよう2グループに分けられるか判定するプログラム
人数 n と2次元配列 enemies が与えられているとします。n は [0, n - 1] のラベルが付けられた n 人の人を表し、enemies の各行は [a, b] という形式で、a と b が敵同士であることを意味します。このとき、n 人を2つのグループに分けて、敵同士が同じグループに含まれないようにできるかどうかを判定する必要があります。 たとえば、入力が n = 4、enemies = [[0, 3],[3, 2]] の場合、出力は True になります。これは [0, 1, 2] と [3] という2つのグループに分ければ、どのグループにも敵同士が存在しないようにできるためで
-
Pythonで捕食関係を考慮した動物の最小グループ数を求めるアルゴリズム
問題概要 数値のリスト nums が与えられます。nums[i] は i 番目の動物の捕食者を表しており、捕食者が存在しない場合は −1 が格納されています。ここで、「どの動物も、自分の直接・間接の捕食者と同じグループに含まれない」ように動物たちをグループ分けすることを考えます。このとき必要となる最小のグループ数を求めるのが目的です。 たとえば、入力が nums = [1, 2, -1, 4, 5, -1] の場合、出力は 3 になります。これは [0, 3]、[1, 4]、[2, 5] のように 3 つのグループへ分割できるためです。 考え方:捕食関係を木構造として捉える 捕食関係は自然に
-
Pythonで0からnまでの全数値のセットビット総数をカウントするプログラム
問題の概要 ある整数 num が与えられたとき、0 ≤ i ≤ num の範囲に含まれる各整数 i について、その2進数表現における「1」の個数(セットビット数)を求めます。 例えば、num が 5 の場合、対象となる数値は [0, 1, 2, 3, 4, 5] です。それぞれを2進数で表すと次のようになります。 0 → 0 → セットビット数 0 1 → 1 → セットビット数 1 2 → 10 → セットビット数 1 3 → 11 → セットビット数 2 4 → 100 → セットビット数 1 5 → 101 → セットビット数 2 したがって、各数値のセットビット数は [0, 1,
-
Pythonでリストを合計が等しくAの全要素がBより小さい2つのグループに分割できるか判定する方法
問題概要数値のリスト nums が与えられたとき、このリストを2つのグループ A と B に分割できるかどうかを判定するプログラムを作成します。分割には以下の2つの条件を満たす必要があります。グループ A の合計とグループ B の合計が等しいことグループ A 内のすべての数値が、グループ B 内のどの数値よりも厳密に小さいこと例えば、nums = [3, 4, 5, 12] という入力の場合、出力は True になります。A = [3, 4, 5]、B = [12] とすれば、両方の合計が12となり、すべての条件を満たすからです。解決アプローチこの問題は、リストをソートして先頭から累積和を確認
-
Pythonで二分探索木のノードの兄弟の値を見つけるプログラム
問題概要 値 k と二分探索木が与えられます。この木では、各ノードは葉ノードであるか、必ず2つの子を持っています。値 k を持つノードを見つけ、その兄弟ノードの値を返す必要があります。 例えば、次のような二分探索木が与えられたとします。 k = 4 の場合、出力は 10 になります(4の兄弟ノードが10だからです)。 解法のアプローチ この問題は、二分探索木の性質(左の子 < 親 < 右の子)を利用することで効率的に解けます。手順は以下の通りです。 関数 util() を定義します。引数として root(現在のノード)、k(探す値)、ans(結果を格納するリスト)を受け取りま
-
Pythonで行列の全行に共通する最小値を見つけるプログラム
問題の概要 各行が昇順にソートされた2次元行列(マトリックス)が与えられたとします。このとき、すべての行に共通して存在する最小の数を見つける必要があります。共通する要素が1つも存在しない場合は、-1 を返します。 例えば、以下のような入力があったとします。 235 51010 135 この場合、3つの行すべてに存在する数は「5」だけなので、出力は 5 となります。 解決のアプローチ この問題は、Pythonの集合(set)の積集合を利用することで、シンプルかつ効率的に解くことができます。具体的な手順は以下の通りです。 行列が空の場合は、-1 を返します。 最初の行の要素から集合を作成
-
【Python】偶数・奇数ごとに配列を並べ替えるパリティソートの実装方法
整数がいくつか格納された配列 A があるとしましょう。この配列を、偶数が先頭側、奇数が後ろ側に来るように並べ替えることを考えます。たとえば、配列が A = [1, 5, 6, 8, 7, 2, 3] であれば、実行結果は [6, 8, 2, 1, 5, 7, 3] のようになります。 アルゴリズムの考え方 この問題は、2つのインデックス(ポインタ)を使った「その場での入れ替え(インプレーススワップ)」によって効率的に解くことができます。手順は次のとおりです。 i = 0、j = 0 で初期化します。 j が配列の長さより小さい間、以下を繰り返します。 arr[j] が偶数であれば、arr[
-
【Python】合計がnに等しくなる数の組み合わせで積を最大化するプログラム
ある整数 n が与えられたとき、「合計が n に等しくなる2つ以上の正の整数」を見つけ、それらの積を最大化する問題を考えます。最終的な答えとして、その最大の積を求める必要があります。例えば、入力が n = 12 の場合、出力は 81 になります。これは、3 + 3 + 3 + 3 = 12 となり、その積は 3 × 3 × 3 × 3 = 81 となるためです。解法のアプローチこの問題は、動的計画法(DP)の考え方を使った再帰関数で効率よく解くことができます。手順は以下の通りです。関数 dp() を定義します。引数として n を受け取ります。n が 0 の場合は 1 を返します(これが再帰の終
-
Pythonで要素をポップして全スタックの合計を揃えるときの最大合計を求めるプログラム
複数のスタック(リスト)が与えられ、その中から任意のスタックを選んで任意の個数の要素をポップ(末尾から取り除く)できるものとします。このとき、すべてのスタックの合計値が等しくなるように操作を行った結果として達成できる最大の合計値を求めるのが本記事のテーマです。たとえば、入力が stacks = [[3, 4, 5, 6], [5, 6, 1, 4, 4], [10, 2, 2, 2]] の場合、出力は 12 になります。具体的には次のような操作で実現できます。1つ目のスタックから 6 をポップ → 残りは [3, 4, 5]、合計は 122つ目のスタックから 4, 4 をポップ → 残りは [
-
Pythonでリスト全体の合計よりも厳密に大きい合計を持つ部分リストが存在するか判定するプログラム
数値のリスト nums が与えられたとき、リスト全体の合計値よりも厳密に大きい合計を持つ部分リスト(連続する要素の並び)が存在するかどうかを判定する問題を考えます。たとえば、nums = [1, -2, 3, 4] の場合を見てみましょう。リスト全体の合計は 6 ですが、部分リスト [3, 4] の合計は 7 となり、6 を上回っています。したがって、この場合の出力は True になります。解法のアプローチこの問題は、累積和を利用することで効率的に解くことができます。手順は以下のとおりです。リストの先頭から順に要素を加算していき(累積和を計算)、途中で合計が負になったら True を返す続いて
-
【Python】値の差とインデックスの差が一致する部分列の最大合計を求める方法
nums という数値のリストがあるとします。このリストから、「値が狭義に増加しており、かつ任意の2つの値の差が、それぞれのインデックス(位置)の差と一致する」という条件を満たす部分列を選びます。そして、そのような部分列の合計の最大値を求めることが目的です。 たとえば、入力が nums = [6, 7, 9, 9, 8, 5] の場合、出力は 22 になります。これは、部分列 [6, 7, 9](対応するインデックスは [0, 1, 3])を選ぶと、隣接する値同士の差が [1, 2] となり、これがインデックスの差と一致するためです。 解法のアプローチ この問題を解くために、以下の手順に従います
-
【Python】二分木が別の木の部分木(サブツリー)かどうかを判定する方法
はじめにプログラミングにおいて、ある二分木が別の二分木の部分木(サブツリー)であるかどうかを判定する処理は、よく登場する基本的な課題の一つです。この記事では、Pythonを使ってこの問題を効率的に解く方法を、具体的なコード例とともにわかりやすく解説します。問題の概要2つの二分木が与えられたとき、「2つ目の木が1つ目の木の部分木になっているか」を確認します。たとえば、次のような入力があった場合:この場合、root2(値4を根とする木)は root1 の中にそのまま含まれているため、出力は True になります。解法のアプローチこの問題は再帰(recursion)を使うことでシンプルに解けます。判
-
Pythonで数独グリッドの有効性を検証するプログラムの実装方法
数独グリッドの有効性検証とは? ここでは、9×9の数独(スドク)グリッドが有効(valid)であるかどうかを判定するプログラムを扱います。検証の対象となるのは、すでに埋められているセルだけであり、次のルールに従ってチェックを行います。 行のルール:各行には、1〜9の数字が重複することなく含まれていること。 列のルール:各列にも、1〜9の数字が重複することなく含まれていること。 ブロックのルール:グリッド内の9つの3×3サブボックス(ブロック)のそれぞれにも、1〜9の数字が重複せずに含まれていること。 例として、次のような数独グリッドを考えてみます。 このグリッドは有効です。 解法のアプ
-
Pythonで合計がkに等しい4つの異なる要素を見つけられるか判定するプログラム
問題の概要 数値のリスト nums と値 k が与えられたとき、リスト内に合計が k と等しくなる4つの異なる要素が存在するかどうかを判定します。 たとえば、入力が nums = [11, 4, 6, 10, 5, 1]、k = 25 の場合、[4, 6, 10, 5] の合計が25になるため、出力は True となります。 解法のアプローチ:ソート + 双方向ポインタ法 この問題は、いわゆる「4Sum」問題と呼ばれるものです。全組み合わせを総当たりすると計算量が膨大になりますが、リストをソートしたうえで双方向ポインタ(two pointers)テクニックを使うことで、効率よく探索できます。
-
Pythonでリスト内の3つの異なる要素の合計がkと一致するか判定するプログラム
数値のリスト nums と値 k が与えられたとき、リストの中から合計が k と等しくなる3つの異なる要素を見つけられるかどうかを判定します。 たとえば、入力が nums = [11, 4, 6, 10, 5, 1]、k = 20 の場合、[4, 6, 10] の合計が 20 になるため、出力は True となります。 解法の考え方 この問題は、リストをソートしたうえで双方向ポインタ(two-pointer)を組み合わせることで、総当たりよりも効率的に解くことができます。手順は以下の通りです。 リスト nums を昇順にソートする 左端を指す l = 0、右端を指す r = len(nums