-
Pythonで括弧列を有効にするための最小追加数を求める方法
問題の概要 ( と ) だけで構成された文字列 S が与えられます。任意の位置に最小限の括弧を追加して、結果として得られる文字列を「有効な括弧列」にすることを考えます。括弧列が有効であるとは、次のいずれかの条件を満たすことを指します。 空文字列である XY(X と Y を連結した形)と表せ、X と Y がどちらも有効な文字列である (A) という形で表せ、A が有効な文字列である たとえば、文字列が "()))((" の場合、これを有効にするには 4 つの括弧を追加する必要があります。 解法のアプローチ この問題はスタックの考え方を使うとシンプルに解決できます。具体的な
-
Pythonで解く「不器用な階乗(Clumsy Factorial)」問題 ― スタックを使った実装方法
正の整数 n の階乗とは、n 以下のすべての正の整数を掛け合わせた値のことです。たとえば factorial(10) = 10 × 9 × 8 × 7 × 6 × 5 × 4 × 3 × 2 × 1 となります。本記事で扱うのは、この階乗をもじった「不器用な階乗(Clumsy Factorial)」という問題です。整数を降順に並べながら、演算子を「掛け算(*)→ 割り算(/)→ 足し算(+)→ 引き算(-)」という固定の順序で循環的に差し替えて計算します。たとえば clumsy(10) は次のように表されます。clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 +
-
PythonでKの倍数となる最小の「1のみの整数」の桁数を求めるアルゴリズム
問題概要正の整数Kが与えられたとき、「各桁がすべて1で構成され、かつKで割り切れる」ような最小の正の整数Nを求めます。答えとなるNの桁数を返し、そのようなNが存在しない場合は-1を返します。例えば、入力が3の場合、出力は3になります。これは、条件を満たす最小の整数が N = 111 だからです。解法のアプローチこの問題は、以下の手順で効率的に解くことができます。Kが偶数、または5で割り切れる場合は-1を返します。1のみで構成される整数の一の位は常に1であるため、偶数にも5の倍数にもなり得ないからです。変数 r を0、N を1で初期化します。i を1からK+1まで繰り返します。r := (r *
-
Pythonで配列を分割して合計を最大化する方法(動的計画法)
問題概要 整数配列 A が与えられたとき、この配列を「長さが K 以下の連続する部分配列」に分割することを考えます。分割後、各部分配列に含まれるすべての要素は、その部分配列内の最大値に置き換えられます。求めたいのは、分割後の配列の合計値として考えられる最大値です。 例えば、入力が [1, 15, 7, 9, 2, 5, 10]、K = 3 の場合、出力は 84 になります。これは、配列を次のように分割できるためです。 [1, 15, 7] → [15, 15, 15](合計 45) [9] → [9](合計 9) [2, 5, 10] → [10, 10, 10](合計 30) 45 +
-
Pythonで1回のスワップで求める「直前の順列」(辞書順で最大の小さい順列)
問題の概要 正の整数からなる配列A(要素は重複していても構いません)が与えられます。この配列に対して、たった1回のスワップ(2つの要素A[i]とA[j]の位置を入れ替える操作)によって作れる順列のうち、Aよりも辞書順に小さく、かつそのような順列の中で最も大きいものを見つける必要があります。条件を満たす順列が存在しない場合は、元の配列をそのまま返します。 例えば、配列が [3, 2, 1] の場合、2と1を入れ替えることで [3, 1, 2] という出力が得られます。 解法のステップ n := 配列Aの長さ left を n−2 から −1 へと降順にループする left == −1 にな
-
Pythonで解く「遠いバーコード」問題:隣接する要素が重複しないように並べ替えるアルゴリズム
問題の概要倉庫に一列に並んだバーコードがあるとします。i番目のバーコードは barcodes[i] で表されます。このバーコードを並べ替えて、どの2つの隣接するバーコードも同じにならないようにするのが課題です。例えば、入力が [1,1,1,2,2,2] の場合、出力は [2,1,2,1,2,1] のようになります。このように、同じ数字が隣り合わない配置を作ることができれば正解です。解法のアプローチこの問題を解くためには、以下の手順に従います。辞書(マップ)d を作成するバーコード配列内の各数値の出現頻度を d に記録する空のリスト x を用意するd のすべてのキーと値のペアを x に挿入するイ
-
【Python】列を反転した後にすべての値が等しくなる行の最大数を求める方法
0と1だけで構成される行列があるとします。この行列では、任意の数の列を選び、その列に含まれるすべてのセルを反転(フリップ)することができます。セルの反転とは、そのセルの値を0から1へ、あるいは1から0へ変更することを意味します。ここで、いくつかの列を反転した後に「すべての値が等しい行」となり得る行の最大数を求める必要があります。 例えば、次のような行列を考えてみましょう。 000001110 この場合の出力は 2 になります。最初の2つの列の値を反転すると、2行目と3行目がそれぞれ同じパターンになり、値が一致するためです。 ポイントとなる考え方 重要なのは、列単位での反転は「行同士の各位置の値
-
Pythonで解く文字タイル問題:DFSで作れる文字列の組み合わせ総数を求める方法
プログラミングの定番問題のひとつに「文字タイル」があります。各タイルには英大文字が1文字ずつ印字されており、これらを自由に並べて作ることができる空でない文字列の総数を求めます。 例えば、入力が AAB の場合、答えは 8 になります。作成可能な文字列は以下の8通りです。 A・B・AA・AB・BA・AAB・ABA・BAA アプローチ:DFS(深さ優先探索)とバックトラッキング この問題は、深さ優先探索(DFS)とバックトラッキングを組み合わせることで効率的に解けます。重要なのは、同じ文字が複数枚あっても「文字ごとの残り枚数」を管理することで、重複する組み合わせを自然に排除できる点です。 dfs関
-
Pythonでラベルごとの使用制限を守りながら最大値の合計を求める方法
この記事では、各アイテムが「値」と「ラベル」を持つ集合から、与えられた制約を満たしながら合計値が最大になる部分集合を見つけるアルゴリズムを、Pythonのコード例とともに解説します。 問題の概要 n個のアイテムがあるとします。i番目のアイテムは値 values[i] とラベル labels[i] を持ちます。ここから部分集合 S を選びますが、S は次の条件を満たす必要があります。 |S| <= num_wanted(選ぶアイテムの総数は num_wanted 以下) どのラベル L についても、S に含まれるラベル L のアイテム数は use_limit 以下 この条件のもとで、部
-
Pythonでカープーリング問題を解く方法
ある車両があり、最初に乗客用の空席が capacity 分だけ用意されているとします。この車両は東方向にしか走行できないため、折り返して西へ戻ることはできません。ここで、trip[i] = [num_passengers, start_location, end_location] という形式の乗車情報リスト trips が与えられます。num_passengers は乗車させる人数、start_location と end_location はそれぞれ乗客を乗せる地点と降ろす地点です。なお、各地点は車両の初期位置から東方向への距離(キロメートル)として表されます。 このモジュールは、与えら
-
Pythonで解く企業のフライト予約問題|差分配列と累積和による効率的な座席集計
n便のフライトがあり、それぞれ1からnまでのラベルが付けられています。ここにフライト予約のリストが与えられ、i番目の予約 bookings[i] = [i, j, k] は「i番からj番までのフライト(両端を含む)でk席を予約した」ことを表します。このとき、各フライトの予約座席数をラベル順に並べた長さnの配列 answer を求めます。例えば、入力が [[1,2,10],[2,3,20],[2,5,25]]、n = 5 の場合、出力は [10, 55, 45, 25, 25] となります。解法のアプローチ:差分配列の活用この問題は、各予約のたびに区間内の全要素へ直接加算すると計算コストが大きく
-
Pythonで最長の好調区間(Well-Performing Interval)を求めるアルゴリズム
問題概要 ある従業員の1日ごとの勤務時間を記録したリスト hours が与えられます。ここで、勤務時間が8時間より厳密に大きい日を「疲労日(tiring day)」と定義します。また、「好調な区間(well-performing interval)」とは、区間内に含まれる疲労日の数が、疲労日以外の日数よりも厳密に多い連続した日数の区間を指します。 このとき、最も長い好調な区間の長さを求めるのが本記事の課題です。たとえば、入力が [9,9,6,0,6,6,9] の場合、出力は 3 となります。これは、最も長い好調な区間が [9,9,6] であるためです。 解法のアプローチ この問題は、累積スコ
-
Pythonでバージョン番号を比較する方法を解説
プログラム開発では、2つのバージョン番号を比較する場面がよくあります。本記事では、Pythonを使ってバージョン番号version1とversion2を比較するアルゴリズムを解説します。 問題の概要 2つのバージョン番号version1とversion2が与えられたとき、以下のルールに従って結果を返します。 version1 > version2 の場合は 1 を返す version1 < version2 の場合は -1 を返す それ以外(等しい場合)は 0 を返す 前提条件 この問題では、以下の条件が成り立つと仮定できます。 バージョン文字列は空ではなく、数字とドット
-
Pythonで指定した範囲の数値リストを生成する3つの方法
Pythonは、豊富なライブラリと多彩なメソッドによって、データ操作に関するあらゆる要件に柔軟に対応できる言語です。たとえば「ある2つの数値の間に存在するすべての数値を生成したい」といった場面では、Pythonの組み込み関数や標準・外部ライブラリを活用することで簡単に実現できます。本記事では、指定範囲内の数値リストを作成する代表的な3つの手法を、サンプルコードとともにわかりやすく解説します。方法1:range()関数を使うrange()関数は、デフォルトでは0から始まり、1ずつ増加しながら指定した数値の手前までの数値シーケンスを返します。開始値・終了値・増加ステップ(間隔)はすべて自由に指定で
-
Pythonでリストを任意の位置で分割してサブリストを作成する方法
データ分析の現場では、データを整形したり移動させたりといった複雑な処理が求められる場面が多くあります。そのような状況で役立つのが、1つの大きなリストを要件に応じて複数のサブリストに分割するテクニックです。本記事では、Pythonでリストを指定した位置で分割するための代表的なアプローチを、具体的なコード例とともに解説します。方法1:zipとforループ(リスト内包表記)を使うこのアプローチでは、まずスライス(リストダイス)を使って分割開始位置から要素を取り出します。次に、zip関数とforループ(リスト内包表記)を組み合わせることで、分割ポイントごとにサブリストを生成します。[0] + spli
-
Pythonで10進数を2進数のリストに変換する方法
Pythonは柔軟性の高いプログラミング言語であり、データ処理の中で発生するさまざまな要件に対応できます。10進数の数値を2進数に変換し、さらに各桁をリストとして扱いたい場合には、以下に紹介する2つの方法が便利です。format関数を使う方法書式指定子(フォーマッター)に使う文字によって、数値を10進数・16進数・8進数・2進数など、任意の基数でフォーマットできます。以下の例では、書式指定として0:0bを使用し、format関数に2進数へ変換したい整数を渡しています。その後、文字列化した2進数を1文字ずつint型に変換してリストを作成します。コード例Dnum = 11 print(与えられた
-
Pythonでリストから指定したインデックスの複数要素を削除する方法
Pythonのリストから単一の要素を削除するのは、del文とインデックスを組み合わせれば簡単に行えます。しかし、複数のインデックスに該当する要素をまとめて削除したいケースでは、少し工夫が必要です。本記事では、削除対象となるインデックスのリストを指定して、元のリストから該当する要素だけを取り除く方法を2つ紹介します。方法1:sorted()とdelを組み合わせるこのアプローチでは、まず削除したい位置(インデックス)を格納したリストを作成します。その後、降順にソートしてから後ろの要素から順に削除することで、削除処理中にインデックスがずれる問題を回避し、元のリストの構造を保ったまま安全に要素を削除で
-
Pythonで辞書を反復処理しながら要素を削除する3つの方法
Pythonの辞書(dict)は、キーと値のペアを格納できる変更可能なコレクションであり、各要素はキーを使って参照します。この記事では、辞書を反復処理しながら要素を削除するための複数の方法を、具体的なサンプルコードと実行結果とともに解説します。del文とキーを使う方法このアプローチでは、まず削除対象となるキーをリスト内包表記で抽出し、その後del文を適用して該当するキーと値のペアをまとめて削除します。サンプルコード# 対象の辞書 ADict = {1: Mon, 2: Tue, 3: Wed, 4: Thu, 5: Fri} # キーが2または3の要素を削除対象として取得 to_del =
-
Pythonで複数のリストから辞書を作成する方法|zipとenumerateの使い方
Pythonでは、リストやタプルといったコレクション型を別の型へ変換したい場面が非常によくあります。本記事では、複数のリストが与えられたときに、それらを組み合わせて1つの辞書(dict)を作成する方法を解説します。ポイントは、ばらばらに存在するリストの要素を、辞書の「キー」と「値」のペアとして正しく対応付けることです。ここでは代表的な2つの手法、「zip関数」と「enumerate関数」を使った方法を、サンプルコードと実行結果つきで紹介します。方法1:zip関数を使って辞書を作成するzip関数を使うと、複数のリストの要素をインデックス順にまとめて取り出せます。以下の例では、3つのリストを入力と
-
Pythonで辞書をタプルのリストに変換する3つの方法
Pythonでは、コレクション型を別の型へ変換するニーズは非常に頻繁に発生します。本記事では、辞書に含まれるキーと値のペアからタプルを作成し、それらをリストにまとめる方法を解説します。各キーと値のペアが1つのタプルになり、最終的な結果は「タプルを要素とするリスト」となります。items()メソッドを使う方法辞書のitems()メソッドを使用すると、キーと値のペアを順番に取り出して反復処理できます。内包表記(またはforループ)でそれぞれのペアをタプルとしてパックし、それらすべてを最終的なリストに格納します。最もシンプルでPythonらしい書き方です。サンプルコードdictA = {Mon: 2