C++

 Computer >> コンピューター >  >> プログラミング >> C++
  1. C++ STLを使った長さ2の異なる連続部分文字列の個数を数える方法

    はじめに本記事では、C++のSTL(標準テンプレートライブラリ)を活用して、与えられた文字列の中に現れる長さ2の異なる連続部分文字列を抽出し、それぞれの出現回数を数えて表示するプログラムについて解説します。問題の概要入力として1つの文字列が与えられます。私たちのタスクは、文字列から隣接する2文字ずつを取り出し、重複を除いたすべての部分文字列(長さ2)とその出現回数を求めて出力することです。例えば、文字列 abcacdcacabacaassddssklac の場合、「ab」「bc」「ca」などのペアが登場します。同じペアが何度現れても1種類として扱い、出現回数を記録するのがポイントです。実装のア

  2. C++で解く単語ラダー(Word Ladder)問題 ― 最短変換シーケンスの求め方

    問題概要2つの単語(beginWord と endWord)と辞書となる単語リストが与えられたとき、beginWord から endWord へ至る最短の変換シーケンスの長さを求めます。ただし、以下のルールに従うものとします。一度に変換できるのは1文字だけです。変換後の各単語は、必ず単語リスト内に存在しなければなりません。beginWord 自体は変換された単語としては扱いません。さらに、以下の点にも注意が必要です。そのような変換シーケンスが存在しない場合は 0 を返します。すべての単語は同じ長さです。すべての単語は小文字の英字のみで構成されます。単語リストに重複はないものと仮定できます。たと

  3. C++で解くn番目のスーパー・アグリー数(超醜い数)― 優先度付きキューを使った効率的な実装

    スーパー・アグリー数とは? スーパー・アグリー数(超醜い数)とは、そのすべての素因数が与えられた素数リスト primes(サイズ k)に含まれる正の整数のことです。 例えば、n = 12、primes = [2, 7, 13, 19] という条件の場合、出力は 32 になります。これは、[1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] という並びが「12個目までのスーパー・アグリー数の列」に該当するためです。 本記事では、この問題を優先度付きキュー(最小ヒープ)を活用して効率よく解く方法を、C++のコード例とともに分かりやすく解説します。 解法のアプロー

  4. C++で解く「House Robber III(二分木の強盗問題)」の解説

    問題の概要ある泥棒が、新たな盗みの場所を見つけました。このエリアへ入れる入り口は一つだけで、「root(根)」と呼ばれています。root以外のすべての家には、必ず親となる家が1つだけ存在します。下見を終えた賢い泥棒は、「この場所のすべての家は二分木を形成している」ことに気づきました。さらに、直接つながっている2つの家が同じ夜に泥棒に入ると、警察へ自動的に通報される仕組みになっています。そこで、警察に通報されることなく今夜盗める金額の最大値を求める必要があります。例として、次のような二分木を考えてみましょう。この場合、出力は 7 となります。解き方のアルゴリズムこの問題は、木構造に対する動的計画

  5. 【C++】文字列内に含まれるすべてのアナグラムの開始位置を検索する方法

    問題概要 文字列 s と空でない文字列 p が与えられたとき、s の中に含まれる「p のアナグラム」が始まるすべての開始インデックスを求めるのがこの問題です。 文字列は小文字アルファベットのみで構成され、s と p の長さはそれぞれ 20 および 100 を超えないものとします。 たとえば、s = cbaebabacd、p = abc の場合、出力は [0, 6] となります。インデックス 0 の位置には cba があり、インデックス 6 の位置には bac があり、どちらも abc のアナグラムだからです。 解決のための手順 この問題は、スライディングウィンドウ(尺取り法)とマップを組み合

  6. C++で解くタスクスケジューラ問題:クールダウン間隔nを考慮した最小実行インターバル数の求め方

    問題概要 CPUが実行すべきタスクを表すchar型の配列を考えます。この配列には大文字A〜Zが含まれ、異なる文字はそれぞれ異なるタスクを表します。タスクは元の順序にとらわれず任意の順番で実行でき、1つのタスクは1インターバル(単位時間)で完了します。各インターバルにおいて、CPUは1つのタスクを実行するか、アイドル状態になるかのどちらかです。 ここで重要になるのが、非負整数のクールダウン間隔 nです。これは、同じタスクを2回実行する間には、少なくともn個のインターバル(別のタスクの実行またはアイドル時間)を挟む必要があるという制約を意味します。この条件下で、与えられたすべてのタスクを完了させる

  7. C++で最も深いノードをすべて含む最小の部分木を求める方法

    問題の概要 ルートを頂点とする二分木が与えられます。各ノードの「深さ」とは、そのノードからルートまでの最短距離のことで、木全体の中で最大の深さを持つノードを「最も深いノード」と呼びます。また、あるノードの「部分木」とは、そのノード自身とそのすべての子孫からなる集合のことです。 この問題では、すべての最も深いノードをその部分木に含むようなノード、すなわち最小の共通部分木の根となるノードを求めます。 たとえば、次のような二分木が与えられたとします。 このとき、求めるべき最小の部分木は次のようになります。 解法のアプローチ この問題は、再帰的な深さ優先探索(DFS)を使うことで効率的に解けます。

  8. C++で生成可能なすべての完全二分木を列挙する方法

    問題の概要 完全二分木(フルバイナリツリー)とは、すべてのノードが子をちょうど0個または2個持つ二分木のことです。この問題では、N個のノードから構成されるすべての完全二分木のリストを求めます。返される木の各ノードの値は0とし、木の並び順は問われません。例えば、入力が7の場合、以下のような木が生成されます。 なお、完全二分木のノード総数は必ず奇数(葉がn個なら全体で2n−1個)になるため、Nが偶数の場合は条件を満たす木が存在しない点にも注意が必要です。 解法のアプローチ この問題は、再帰とメモ化(計算結果のキャッシュ)を組み合わせることで効率的に解くことができます。具体的な手順は以下の通りで

  9. C++で部分配列の最小値の合計を求める方法【単調スタックでO(N)高速化】

    整数配列 A が与えられたとき、A のすべての(連続する)部分配列 B に対する min(B) の合計を求める問題を考えます。答えは非常に大きな値になる可能性があるため、109 + 7 で割った余りを返します。たとえば、入力が [3,1,2,4] の場合を考えてみましょう。部分配列は [3]、[1]、[2]、[4]、[3,1]、[1,2]、[2,4]、[3,1,2]、[1,2,4]、[3,1,2,4] の 10 個存在し、それぞれの最小値は [3,1,2,4,1,1,2,1,1,1] となります。これらの合計は 17 であるため、出力は 17 になります。解法のアプローチ:単調スタックすべての

  10. C++で実装する完全二分木インサーター(CBTInserter)の解説とコード例

    完全二分木(Complete Binary Tree)とは、最後のレベルを除くすべてのレベルが完全に埋まっており、かつ最後のレベルのノードはすべて可能な限り左に寄せられている二分木のことです。本記事では、完全二分木を初期状態として受け取り、以下の操作をサポートするデータ構造 CBTInserter をC++で実装する方法を解説します。CBTInserter(TreeNode root):ルートノード root を持つ木を初期化します。CBTInserter.insert(int v):値 v を持つノードを挿入し、木が完全二分木の状態を保つようにします。挿入されたノードの親の値を返り値として返

  11. C++で二分木の最大レベル合計を求めるアルゴリズム

    問題概要二分木(バイナリツリー)のルートノードが与えられたとき、ルートのレベルを1とし、その子ノードをレベル2、さらにその下をレベル3として数えていきます。このとき、「全ノードの値の合計が最大になる最小のレベルX」を求めて返すのが本問題の目的です。例えば、次のような二分木を考えてみましょう。この場合の出力は「2」となります。各レベルの合計を計算すると以下のようになります。レベル1の合計:1レベル2の合計:7 + 0 = 7レベル3の合計:7 + (-8) = -1最大の合計はレベル2の「7」であるため、答えは2になります。解法のアプローチこの問題は、幅優先探索(BFS)を使って各レベルごとのノ

  12. C++で複数の棒を1本に接続する際の最小コストを求めるアルゴリズム

    問題の概要 正の整数の長さを持つ複数の棒があると仮定します。長さが X と Y の2本の棒を1本に接続するときのコストは X + Y です。この操作を、棒が1本だけ残るまで繰り返します。ここで、与えられたすべての棒をこの方法で1本にまとめるときの最小コストを求めることが目的です。 例えば、棒の長さの配列が [2, 4, 3] の場合、出力は 14 になります。実際の手順としては、まず 2 と 3 を接続して 5 を作り(コスト 5)、次に 5 と 4 を接続して 9 を作る(コスト 9)ので、合計コストは 5 + 9 = 14 となります。他の接続順序ではコストが大きくなるため、これが最適解で

  13. C++で要素を1つまで削除して得られる最大部分配列和を求める方法

    整数の配列が与えられたとき、最大で1つの要素を削除できる非空(空でない)の連続部分配列における最大の合計値を求める問題を考えてみましょう。言い換えると、ある部分配列を選び、必要に応じてその中から1つの要素だけを取り除き、残った要素の合計が最大になるようにするというものです。ただし、削除を行った後でも部分配列には少なくとも1つの要素が残っている必要がある点に注意してください。たとえば、入力が [1,-2,0,3] の場合、出力は 4 になります。-2 を削除すれば、残りの要素の合計 1+0+3=4 が最大となるためです。 解法のアプローチ この問題は動的計画法(DP)を用いることで、線形時

  14. C++で解く「2つの二分探索木の合計(Two Sum BSTs)」問題

    問題概要2つの二分探索木(BST)が与えられたとき、1つ目の木から選んだあるノードと、2つ目の木から選んだあるノードの値の合計が、指定された整数 target と一致する場合に true を返すプログラムを作成します。それ以外の場合は false を返します。例えば、次のような2つの木があるとします。このとき target が 5 であれば、結果は true になります。実際に確認してみると、1つ目の木のノード 2 と2つ目の木のノード 3 の合計が 5、また 1つ目の木のノード 4 と2つ目の木のノード 1 の合計も 5 となるため、条件を満たすペアが存在します。解法のアプローチこの問題は、

  15. C++で指定した差分を持つ最長等差部分列を求める方法

    問題概要 整数配列 arr と整数 difference が与えられたとき、隣接する要素同士の差がすべて difference と一致するような等差数列をなす最長部分列の長さを求めます。 たとえば、入力が [1,5,7,8,5,3,4,2,1]、difference が -2 の場合を考えてみましょう。このとき最長の等差数列は [7,5,3,1] となるため、答えは 4 になります。 解法のアプローチ この問題は、連想配列(マップ)を用いた動的計画法によって線形時間で効率的に解くことができます。ポイントは、「その値で終わる等差部分列の最大長」を各要素ごとに記録していくことです。具体的には次の

  16. C++でリーダーボードクラスを設計する方法

    ここでは、ゲームなどで使われるリーダーボード(順位表)を管理する Leaderboard クラスを C++ で設計します。このクラスには、次の3つの操作が必要です。addScore(playerId, score) — 指定したプレイヤーのスコアに score を加算してリーダーボードを更新します。該当する ID のプレイヤーがまだ存在しない場合は、そのスコアで新規登録します。top(K) — 現在の上位 K 人のプレイヤーのスコア合計を返します。reset(playerId) — 指定した ID のプレイヤーのスコアを 0 にリセットします。この関数が呼ばれる時点で、そのプレイヤーはすでにリ

  17. C++で木の直径を求めるアルゴリズムを解説

    木の直径とは無向木(undirected tree)が与えられたとき、その直径を求めることを考えます。木の直径とは、木の中で最も長い経路に含まれる辺の数のことです。ここでは、木は辺のリストとして与えられます。edges[i] = [u, v] は、ノードuとノードvをつなぐ双方向の辺を表します。また、各ノードには {0, 1, ..., edges.length} の集合からラベルが割り当てられています。例として、次のような木を考えてみましょう。この場合、最も長い経路の長さは4となるため、出力は4になります。解法のアプローチ木の直径を効率的に求めるには、DFS(深さ優先探索)を2回実行するとい

  18. C++で文字列を等しくするための最小スワップ回数を求めるアルゴリズム

    問題概要「x」と「y」のみで構成された、同じ長さの2つの文字列 s1 と s2 が与えられます。目標は、これらの文字列を互いに等しくすることです。操作としては、異なる文字列に属する任意の2文字を入れ替えることができます。つまり、s1[i] と s2[j] をスワップします。s1 と s2 を等しくするために必要な最小のスワップ回数を求め、どうしても不可能な場合は -1 を返してください。例えば、s1 = xy、s2 = yx の場合、答えは 2 になります。まず s1[0] と s2[0] をスワップすると、s1 = yy、s2 = xx となります。次に s1[0] と s2[1] をスワッ

  19. C++でk個の奇数を含む「良い部分配列」の個数を数える方法

    整数型の配列 nums と整数 k が与えられます。部分配列に含まれる奇数の個数がちょうど k 個であるとき、その部分配列を「良い部分配列(nice subarray)」と呼びます。この記事では、条件を満たす良い部分配列の個数を求めるアルゴリズムを解説します。 例として、配列が [1,1,2,1,1]、k = 3 の場合を考えてみましょう。このとき出力は 2 になります。条件を満たす部分配列は [1,1,2,1] と [1,2,1,1] の2つだからです。 解法の考え方 まず、配列中に現れる奇数のインデックスをすべて記録した配列 odd を作成します。次に、連続する k 個の奇数からなるウィン

  20. C++で区間リストから指定範囲を削除するアルゴリズムと実装例

    問題の概要ソート済みの互いに重ならない区間リストが与えられたとします。各区間 intervals[i] = [a, b] は、a <= x < b を満たす数値 x の集合を表します。このリスト内の各区間と、指定された区間 toBeRemoved との共通部分(重なり)をすべて取り除き、処理後の区間をソート済みリストとして返すのが目的です。例えば、入力が [[0,2], [3,4], [5,7]]、toBeRemoved が [1, 6] の場合、出力は [[0, 1], [6, 7]] となります。解決のための手順補助関数 manipulate2() の定義まず、行列 a と配列

Total 5990 -コンピューター  FirstPage PreviousPage NextPage LastPage CurrentPage:146/300  20-コンピューター/Page Goto:1 140 141 142 143 144 145 146 147 148 149 150 151 152