-
Pythonでリストの先頭・末尾からK個の要素を削除したときの最大合計を求めるプログラム
問題概要数値のリスト nums と整数 k が与えられます。リストに対してちょうど k 回の削除(ポップ)操作を行う必要があり、各操作ではリストの左端または右端のいずれかから要素を取り除くことができます。このとき、削除した要素の合計値が最大になるように求めるのが目標です。たとえば、入力が nums = [2, 4, 5, 3, 1]、k = 2 の場合、出力は 6 になります。これは、先頭から 2 と 4 を削除することで合計 6 が得られるためです。解法のアプローチ:スライディングウィンドウこの問題は「スライディングウィンドウ」の考え方を使うと効率的に解けます。まず、先頭から k 個の要素を
-
Pythonで長さxとyの重ならない2つのサブリストの最大合計を求める方法
問題概要 数値のリスト nums と整数 x、y が与えられたとき、それぞれ長さが x と y であり、互いに重なり合わない2つのサブリスト(部分リスト)を選び、その要素の合計の最大値を求めるのが今回の課題です。 たとえば、nums = [3, 2, 10, -2, 7, 6]、x = 3、y = 1 という入力の場合、出力は 22 になります。これは、長さ3のサブリストとして [3, 2, 10] を、もう一方として [7] を選んだ場合の合計(15 + 7 = 22)に該当します。 解法のアプローチ:累積和(Prefix Sum)を活用 この問題は、累積和を使うことで線形時間 O(n) で
-
PythonでMin-maxゲーム木を埋めるプログラムの書き方
二人対戦ゲームの局面を表す二分木を考えてみましょう。すべての内部ノードは 0 で初期化されており、葉ノードの値がその局面の最終スコアを表しています。プレイヤー1は最終スコアを最大化することを目指し、プレイヤー2は最小化することを目指します。プレイヤー1は必ず偶数レベル(ルートをレベル0とする)のノードで手を打ち、プレイヤー2は奇数レベルのノードで手を打つものとします。このとき、両プレイヤーが最適な手を打った場合の結果スコアで、二分木の各ノードを埋めていく必要があります。たとえば、次のような入力が与えられた場合:出力は次のようになります:解決のアプローチこの問題は、Min-max法として知られる
-
Pythonプログラム:2つのリストを厳密に増加列にするための最小スワップ回数を求める
同じ長さを持つ2つの数値リストAとBが与えられているとします。ここで、A[i]とB[i]の値を入れ替える(スワップする)という操作を実行できるものとします。このとき、両方のリストを厳密に増加する列(各要素が直前の要素より必ず大きい列)にするために必要な最小の操作回数を求めるのがこの問題です。 例えば、入力が A = [2, 8, 7, 10]、B = [2, 4, 9, 10] の場合、出力は 1 になります。これは、Aの「7」とBの「9」を一度だけ入れ替えることで、A = [2, 8, 9, 10]、B = [2, 4, 7, 10] となり、どちらのリストも厳密に増加する列になるからです
-
【Python】2つのペアの合計差が最小になる数値の組み合わせを見つけるプログラム
問題の概要数値のリスト nums が与えられたとき、その中から2組の数値ペアを選び、それぞれのペアの合計値の絶対差が最小になるような組み合わせを求めたいとします。例えば、入力が nums = [3, 4, 5, 10, 7] の場合、出力は 1 になります。これは、(3 + 7) と (4 + 5) という2組のペアを選ぶことで、(3 + 7) - (4 + 5) = 1 という最小の差が得られるためです。解決のためのアルゴリズムこの問題は、以下の手順に従って解くことができます。空のリスト distances を用意します。i を 0 から nums のサイズ - 2 まで繰り返します。j を
-
Pythonで解く!連続する3要素の各グループから1つ以上を選ぶ最小合計部分列の求め方
問題の概要 数値のリスト nums が与えられたとき、連続する3つの数値からなるどのグループにも、選んだ要素が少なくとも1つ含まれるという条件を満たす中で、合計が最小になる部分列(サブシーケンス)を見つける問題です。リストの長さが3未満の場合でも、少なくとも1つの要素は選択する必要があります。 具体例で理解する たとえば、入力が nums = [2, 3, 4, 5, 6, 7] の場合を考えてみましょう。「2」と「5」を選ぶと、3連続のグループ [2, 3, 4]、[3, 4, 5]、[4, 5, 6]、[5, 6, 7] のすべてに選択要素が含まれ、合計は 2 + 5 = 7 になります。
-
Pythonで葉ノードのリストから最小合計となる木を構築して合計値を求める方法
問題の概要 数値のリスト nums が与えられます。このリストは、ある二分木を中順走査(inorder traversal)した際の葉ノードを表しています。この木には次のようなルールがあります。 すべての内部ノードは必ず2つの子を持ちます。 内部ノードの値は、「左部分木における最大の葉の値」と「右部分木における最大の葉の値」の積になります。 この条件のもとで、ノード値の合計が最小になるような木を構成し、その合計値を求めるのが目的です。 入出力の例 たとえば、入力が nums = [3, 5, 10] の場合、出力は 83 となります。最小の葉「3」に隣接する「5」を掛けて結合し、次に「5」
-
Pythonで最大k回の増加操作後に最も頻出する数を求めるプログラム
問題の概要 数値のリスト nums と整数 k が与えられます。「リスト内の任意の要素を1つ選び、その値を1だけ増やす」という操作を最大 k 回まで行えるとき、操作後に最も多く出現することになる数の値を求めてください。候補が複数ある場合は、そのうち最も小さい値を返します。 たとえば nums = [1, 0, 0, 0, 8, 8, 8, 8]、k = 8 の入力を考えてみます。値 1 を7回増やして 8 にすれば、残りの1回で 0 のいずれかを 1 にできます。結果は [8, 1, 0, 0, 8, 8, 8, 8] となり、8 が5個並ぶため、答えは 8 になります。 アプローチ:スライデ
-
Pythonですべての映画を上映するために必要な映画館の最小数を求めるプログラム
複数の映画の上映時間を表す区間のリストが与えられます(区間同士は重なる場合があります)。このとき、すべての映画を上映するために最低限必要な映画館の数を求める問題を考えてみましょう。例えば、入力が intervals = [[20, 65], [0, 40], [50, 140]] の場合、出力は 2 になります。これは、[20, 65] と [0, 40] が重なっており、[20, 65] と [50, 140] も重なっていますが、[0, 40] と [50, 140] は重なっていないためです。つまり、同時に上映されている映画の最大本数が2本なので、2つのスクリーン(映画館)があれば十分だ
-
【Python】動的計画法で合計がkになる組み合わせの数を求める方法
重複のない整数のリスト nums と、ある数値 k が与えられたとき、要素の合計がちょうど k になる組み合わせが何通り存在するかを求めます。なお、組み合わせを作る際には、同じ数字を何度でも繰り返し使って構いません。たとえば、入力が nums = [2, 4, 5]、k = 4 の場合、出力は 2 になります。[2, 2] と [4] の2通りの作り方が存在するためです。解法のアプローチ(動的計画法)この問題は、いわゆる「コイン両替問題」と同型で、動的計画法(DP)を使うことで効率的に解けます。考え方の手順は以下の通りです。サイズが k+1 のリスト table を用意し、すべて 0 で初期化
-
Pythonで辞書式順序の最初のn個の数を生成するプログラム
はじめに数値 n が与えられたとき、「辞書式順序(lexicographic order)」に従って並べ替えられた最初の n 個の数を求めることを考えます。辞書式順序とは、数値を文字列として扱い、左から1文字ずつ比較して並べる方式のことです。例えば、入力が n = 15 の場合、出力は次のようになります。[1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9]これは通常の数値の大小順(1, 2, 3, …)ではなく、「1」の次に「10」「11」「12」と続く、文字列として比較したときの順序になっている点に注目してください。解決アプローチこの問題は、
-
Pythonで辞書式順序k番目に小さい長さnの文字列を求めるプログラム
問題の概要 数値 n と値 k が与えられた場面を考えてみましょう。ここで扱うのは、「0」「1」「2」の3種類の文字だけで構成され、同じ文字が連続して現れないという条件を満たす文字列です。この条件を満たす長さ n の文字列の中から、辞書式順序で k 番目に小さい文字列を求めます。該当する文字列が存在しない場合は、空文字列を返します。 たとえば、入力が n = 4、k = 2 の場合、出力は 0120 となります。 これは、条件を満たす長さ4の文字列を辞書式順序に並べると「0101」「0102」「0120」「0121」…となるため、k = 2 に対応する文字列が 0120 だからです。 解決
-
Pythonで各桁が非減少となるn以下の最大の数を求めるプログラム
問題の概要ある整数 n が与えられたとき、「すべての桁が非減少(左から右へ見て、どの桁もひとつ前の桁以上である)」という条件を満たす、n 以下の最大の数を求めます。たとえば入力が n = 221 のとき、出力は 199 になります。221 は「2 → 1」という減少を含むため条件を満たさず、条件を満たす数の中で最も大きいものが 199 だからです。解法のアプローチこの問題は、次の手順で解くことができます。n の各桁をリスト digits として取り出します。減少が発生した位置を記録するための変数 bound を用意します。右端の桁から左へ向かって走査します。digits[i] < dig
-
Pythonで合計が1になる分数ペアの数をカウントするプログラム
分子と分母を [分子, 分母] の形式のリストで表した分数のリストが与えられます。各要素は「分子 ÷ 分母」という数値を表しています。ここでの課題は、足し合わせると合計が 1 になる分数のペアがいくつあるかを求めることです。例えば、入力が fractions = [[2, 7], [3, 12], [4, 14], [5, 7], [3, 4], [1, 4]] の場合、出力は 4 になります。(2/7 + 5/7)、(3/12 + 3/4)、(3/4 + 1/4)、(4/14 + 5/7) の 4 つのペアが、いずれも合計 1 となるためです。解き方のアルゴリズムこの問題は、各分数を最大公約
-
平均がターゲット以上となる長さKのサブリストの数を求めるPythonプログラム
問題の概要 リスト nums と、2つの値 k および target が与えられたとします。このとき、「要素数がちょうど k であり、その平均値が target 以上であるサブリスト」の個数を求めるのが今回の課題です。 たとえば、入力が nums = [1, 10, 5, 6, 7]、k = 3、target = 6 の場合を考えてみましょう。このとき出力は 2 となります。サブリスト [1, 10, 7] の平均値は 6、サブリスト [10, 5, 6] の平均値は 7 となり、条件を満たすものが2つ存在するためです。 アルゴリズムの考え方 この問題は「スライディングウィンドウ(移動窓)」と
-
【Python】合計がターゲット値と一致するサブリストの個数を効率的に求める方法
数値のリスト nums とターゲット値 target が与えられたとき、要素の合計が target と一致するサブリスト(連続する部分列)がいくつ存在するかを求める問題について解説します。たとえば、nums = [3, 0, 3]、target = 3 という入力の場合、答えは 4 になります。これは、合計が 3 になるサブリストとして [3]、[3, 0]、[0, 3]、[3] の 4 つが存在するためです。解法のアプローチ:累積和とハッシュマップすべてのサブリストを総当たりで調べると O(n²) の時間がかかりますが、累積和(プレフィックスサム)と辞書(ハッシュマップ)を組み合わせることで
-
Pythonでリストを昇順ソートするのに必要な最小スワップ回数を求めるアルゴリズム
問題の概要 重複のない数値のリストが与えられたとき、そのリストを昇順に並べ替えるために必要な最小スワップ(要素の交換)回数を求めます。 具体例 たとえば、入力が nums = [3, 1, 7, 5] の場合を考えてみましょう。 「3 と 1 を交換」→ [1, 3, 7, 5] 「5 と 7 を交換」→ [1, 3, 5, 7] 以上の 2 回の操作で昇順に並べ替えられるため、出力は 2 となります。 アルゴリズムの手順 この問題は、「各位置に本来置かれるべき値」を順番に正しい場所へ入れ替えていくことで解くことができます。手順は以下の通りです。 sort_seq:元のリスト nums
-
Pythonで二分木に含まれる一人っ子ノードの数を数えるプログラム
二分木が与えられたとき、「一人っ子ノード」——つまり、親が持つ唯一の子であるようなノード——の数を求めることを考えます。あるノード x が一人っ子ノードであるとは、その親ノードが x だけを子として持ち、左か右のどちらか片方しか子を持たない場合を指します。 例として、次のような二分木を考えてみます。 この木では、ノード 8 とノード 6 がそれぞれ親(7 と 10)の唯一の子となっているため、出力は 2 になります。 アルゴリズムの流れ 幅優先探索(BFS)を用いて、木を上から順に走査しながら一人っ子ノードを数えていきます。手順は以下の通りです。 ルートが null の場合は 0 を返す
-
Pythonでk回の操作後に実現可能な最小の最大値を求めるプログラム
数値のリスト nums と整数 k が与えられたとします。ここで考える「操作」とは、リスト内の任意の要素から 1 を引くことです。この操作は合計 k 回まで実行できます。目標は、k 回の操作を行った後のリストにおいて、最大値が取り得る最小の値を求めることです。 たとえば、入力が nums = [3, 4, 6, 5]、k = 6 の場合、出力は 3 になります。これは、4 を 1 回、6 を 3 回、5 を 2 回減らすことで、リスト全体を [3, 3, 3, 3] にできるためです。 解法の考え方 この問題は貪欲法(グリーディ法)で効率的に解くことができます。基本の発想は、「現在の最大値と同
-
Pythonで選択パターンから生成可能なすべての文字列を求めるプログラム
問題の概要 小文字のアルファベットと、「[」「|」「]」といった特殊文字で構成された文字列 s が与えられるとします。ここで「[a|b|c]」という表記は、「a」「b」「c」のいずれか1つを選択できることを意味します。このとき、文字列 s が表現しうるすべての値を含むリストを作成する必要があります。なお、「[]」の入れ子(ネスト)は禁止されており、選択肢の数は任意とします。 例えば、入力が s = [d|t|l]im[e|s] の場合、出力は次のようになります。 [dime, dims, lime, lims, time, tims] 解決のための手順 この問題は、再帰的なバックトラッキング(