-
C++で二分木の各レベルの平均値を求めるアルゴリズムと実装方法
問題の概要空でない二分木(バイナリツリー)が与えられたとき、各レベル(階層)に存在するノードの値の平均を計算し、その結果を配列として返すことを考えます。例えば、次のような二分木が入力として与えられた場合を考えてみましょう。この木は3つのレベルで構成されており、出力は [3, 14.5, 11] となります。具体的には以下のように計算されます。第1レベル:ノード 3 のみ → 平均は 3第2レベル:ノード 9 と 20 → 平均は (9 + 20) / 2 = 14.5第3レベル:ノード 15 と 7 → 平均は (15 + 7) / 2 = 11解決のためのアプローチこの問題は、BFS(幅優先
-
C++で長さkの部分配列の最大平均を求める方法(スライディングウィンドウ)
この記事では、n個の要素を持つ配列から、指定された長さkの連続する部分配列の中で平均値が最大となるものを見つけ、その最大平均値を返す方法を解説します。問題の概要例として、入力が [1,13,-5,-8,48,3]、k = 4 の場合を考えてみましょう。このとき出力は 12.0 になります。これは (13 + (-5) + (-8) + 48) / 4 = 12.0 となるためです。アルゴリズム:スライディングウィンドウこの問題は「スライディングウィンドウ(滑動窓)」という手法を使うと効率的に解けます。毎回k個の要素を足し直す代わりに、ウィンドウを1つずらすたびに「新しい要素を加え、古い要素を引
-
C++でセットの不一致問題を解く:重複した数と欠落した数を見つける方法
1からnまでの数字を含む集合Sがあるとします。ところが、何らかのエラーによって、集合内のある数字が別の数字の位置に誤って記録されてしまい、その結果、ある一つの数字が重複し、別の一つの数字が失われるという状態になりました。ここで、エラー発生後の集合の状態を表す配列numsが与えられます。私たちのタスクは、2回出現している数字と失われた数字を見つけ出し、その結果を配列として返すことです。例えば、入力が [1,2,3,4,4,6] の場合、4が重複しており5が欠落しているため、出力は [4,5] となります。解法のアプローチこの問題を解くために、以下の手順に従います。サイズ2の結果格納用配列 v を
-
C++で解くTwo Sum IV ― 二分探索木(BST)が入力の場合
問題概要 二分探索木(BST)とターゲット値が1つ与えられます。このとき、BST内に「2つの要素の和がターゲット値と等しくなる」ような組み合わせが存在するかどうかを判定するのが本問題です。 例えば、次のような木が入力として与えられた場合を考えてみましょう。 この場合、出力は True(真)となります。 解法のアプローチ この問題は、BSTを中間順(inorder)走査して昇順の配列を作り、その後「双方向ポインタ(two pointer)」を使うことで効率的に解けます。具体的には、以下の手順に従います。 値を格納するための配列 v を定義します。 関数 inorder() を定義します(引
-
【C++】ロボットが移動後に原点(0,0)へ戻るかどうかを判定するアルゴリズム
あるロボットがあり、その初期位置は (0, 0) だとします。ここで、ロボットの一連の移動手順が与えられたとき、すべての移動を完了した後、このロボットが元の位置 (0, 0) に戻っているかどうかを判定する必要があります。移動の手順は文字列として与えられ、moves[i] が i 番目の移動を表します。各記号の意味は以下の通りです。R:右へ移動L:左へ移動U:上へ移動D:下へ移動ロボットがすべての移動を終えた時点で原点に戻っていれば true を返し、そうでなければ false を返します。たとえば、入力が RRULLD の場合、出力は true になります。これは、右へ2単位進み、次に上へ移
-
C++で実装する画像スムーザー:周囲8ピクセルとの平均値で画像を平滑化する方法
ここでは、画像のグレースケール値を表す2次元行列 M が与えられたとき、各ピクセルの値を「自分自身と周囲8ピクセルのグレースケール値の平均(小数点以下は切り捨て)」に置き換えるスムーザー(平滑化フィルタ)を設計します。なお、端や角にあるセルのように周囲のセルが8個より少ない場合は、存在するすべてのピクセルを使って平均を計算します。問題の例たとえば、次のような入力が与えられたとします。111101111この場合、出力は次のようになります。000000000中央の0以外のピクセルは、それぞれ自分自身を含む9マスの平均が 8/9 ≒ 0.88 となり、切り捨てると0になるためです。解法のアプローチこ
-
C++でサイズkの部分列における最大積を求めるアルゴリズム
この問題では、整数の配列 arr[] と数値 k が与えられ、サイズ k の部分列のうち要素の積が最大になるものを求めるプログラムを C++ で作成します。 問題の概要 サイズ k(1 ≤ k ≤ n)の部分列の中から、その要素の積が最大となるものを見つけることが目的です。 入力例 arr[] = {1, 5, 6, -2, 0, 4} , k = 3 出力例 120 説明 サイズ 3 の部分列の中で最大の積となるのは (5, 6, 4) であり、その積は 120 です。 解決アプローチ この問題を解くには、まず配列 arr[] をソートし、その後、配列の要素の値と k の値に応じて処理方法を
-
C++で木構造における交差しない2つのパスの最大積を求める方法
本記事では、n個のノードからなる無向連結木Tが与えられたとき、互いに交差しない2つのパスの長さの積として考えられる最大値を求めるC++プログラムを作成します。 問題の説明 木構造の中から、共通の頂点や辺を一切共有しない「交差しないパス」を2つ選び出し、それぞれのパスの長さ(辺の数)を掛け合わせます。そして、その積が最大になるようなパスの組み合わせを見つけるのがこの問題の目的です。 具体例を使って問題を確認してみましょう。 入力 グラフ − 出力 8 解説 この例では、C-A-B と F-E-D-G-H の2つのパスが互いに交差していません。それぞれの長さは2と4であるため、積は 2 × 4
-
C++で配列の最大積クアドラプル(サイズ4の部分列)を求める方法
問題の概要 本記事では、配列 arr[] が与えられたとき、その中から積が最大となる4つの要素(サイズ4の部分列=クアドラプル)を見つけるプログラムをC++で実装する方法を解説します。 問題の説明:配列から任意の4つの要素を選び、それらの積が最大になる組み合わせを求めることが目的です。 まず、具体例で問題を確認してみましょう。 入力 arr[] = {4, -2, 5, -6, 8} 出力 480 説明 積が最大となるのは (-2, 5, -6, 8) の組み合わせで、(-2) × 5 × (-6) × 8 = 480 となります。負の数同士を掛けると正になるため、負の要素を含む組み合わせが最
-
C++で2回の走査を用いて最大積部分配列(Maximum Product Subarray)を求める方法
この問題では、整数型の配列 arr[] が与えられます。求められているのは、C++において「2回の走査(Two Traversals)」を利用して最大積部分配列(Maximum Product Subarray)を求めるプログラムです。 問題の説明 − 配列の中から最大の積を持つ部分配列を見つけます。具体的には、インデックス0から開始する「左から右への走査」と、インデックス(n-1)から開始する「右から左への走査」という2方向のトラバーサルを組み合わせて解を導き出します。 具体例で問題を確認してみましょう。 入力 arr[] = {4, -2, 5, -6, 0, 8} 出力 240 解説
-
最大積部分配列を求める|C++で負の数を含むケースに対応
この問題では、正の整数と負の整数が混在する配列が与えられます。C++を用いて、配列の中から積が最大となる部分配列(Maximum Product Subarray)を計算するプログラムを作成することが課題です。問題の概要 − 扱う配列には、正の数・負の数・0が含まれています。配列の要素から作られる部分配列(連続する要素の集まり)の積を求め、その積が最大になる組み合わせを見つける必要があります。具体例で問題を確認しましょう入力arr[] = {-1, 2, -7, -5, 12, 6}出力5040説明積が最大となる部分配列は {2, -7, -5, 12, 6} です。積 = 5040解法のアプ
-
C++で配列の最大積サブセットを求めるアルゴリズムと実装方法
このチュートリアルでは、配列の中から部分集合を選び、その積が最大になる値を求めるプログラムについて解説します。 ここでは、正の値と負の値が混在する配列が与えられます。私たちのタスクは、この配列の部分集合の中で積が最大となるものを見つけることです。 アルゴリズムの考え方 最大積を求めるための基本的な戦略は以下の通りです。 0は乗算に含めない:0を掛けると積が0になってしまうため、計算から除外します。 負の数の扱い:負の数が偶数個ある場合はすべて掛けて問題ありません。奇数個の場合は、絶対値が最も小さい(0に最も近い)負の数を除外することで、積を最大化できます。 全要素が0の場合:配列のすべての
-
C++で株式の売買から得られる最大利益を計算する方法
この問題では、i日目の株価を表す配列 stkprice[] が与えられ、C++で株式の売買によって得られる最大利益を計算するプログラムを作成します。 問題の概要 ここで求められているのは、いつ株を買い、いつ売れば利益を最大化できるかを見極めることです。利益を生むためには、株価が安いときに購入し、価格が上昇したタイミングで売却します。その後、再び価格が下落した局面が現れたら、同じ売買サイクルを繰り返します。 具体例を使って問題を理解しましょう。 入力 stkprice[] = {120, 310, 405, 210, 150, 550} 出力 685 説明 1日目に購入して3日目に売却すると、2
-
C++で配列から最大の有理数(分数)を求める方法
この記事では、有理数が1行に1つずつ格納された2次元配列から、最大の有理数(分数)を求めるC++プログラムの作成方法について解説します。 問題の説明 与えられる2次元配列は [n][2] の形式です。各行には2つの整数値が含まれており、これらは有理数 a/b を表す分子 a と分母 b に対応します。私たちのタスクは、配列内のすべての有理数の中から最も大きい値を見つけることです。 具体例を使って問題を理解しましょう。 入力例 rat[][] = { {3, 2}, {5, 7}, {1, 9}, {11, 4} } 出力例 11 4 解説 3/2、5/7、1/9
-
C++でバイナリ行列を最大K回反転したときの最大スコアを求める方法
この記事では、0と1(ブール値)で構成される2次元配列 arr[] と整数 K が与えられたとき、バイナリ行列を最大 K 回反転した後の最大スコアを求めるプログラムを C++ で作成します。 問題の説明 2次元配列と K 回までの操作が与えられます。各操作では、任意の行または列を選び、その行(または列)に含まれるすべての要素を反転します(0 を 1 へ、1 を 0 へ)。操作の選択は、K 回の反転を行った後に、行列の各行が表す2進数の値が最大になるように行います。そして、各行で作られる数値の合計を答えとして返します。 具体例を使って問題を理解しましょう。 入力 arr[][] = {
-
C++で隣接要素を考慮せずに配列のセットビット数の合計を最大化する方法
この問題では、整数型の配列 arr[] が与えられ、隣接する要素を選ばないという条件下で、配列内のセットビット(1になっているビット)数の合計が最大になるように求めるプログラムをC++で作成します。問題の概要ここで扱うのは、配列 arr[] の各要素についてセットビットの数を数え、隣接しない要素同士(例えば a[i] + a[i+2] のように1つ飛ばしで選んだ要素)のセットビット数の合計が最大となる値を求めるというものです。具体例で問題を理解しよう入力arr[] = {1, 4, 6, 7}出力4解説まず、各要素を2進数で表すと次のようになります。arr[] = {01, 100, 101,
-
C++で指定された条件を満たす部分配列の最大サイズを求める方法
はじめに このチュートリアルでは、指定された条件を満たす部分配列(サブ配列)の最大サイズを求めるC++プログラムについて解説します。この問題は、隣接する要素同士の大小関係が交互に入れ替わる「ジグザグ(乱流)パターン」を持つ、最長の連続区間を見つけるというものです。 問題の定義 整数型の配列が与えられたとき、次のいずれかの条件を満たす最長の部分配列を求めます。 条件A: kが奇数のとき arr[k] > arr[k+1]、kが偶数のとき arr[k] < arr[k+1] 条件B: kが偶数のとき arr[k] > arr[k+1]、kが奇数のとき arr[k] < a
-
C++で1のみを含む最大サイズの長方形部分行列を見つける方法
このチュートリアルでは、すべての要素が1である最大サイズの長方形部分行列(バイナリサブマトリックス)を見つけるプログラムについて解説します。0と1のみで構成された2次元行列が与えられ、その中から「1だけで構成される最も大きな部分行列」の面積を求めるのが課題です。アルゴリズムの考え方この問題は、「ヒストグラムの中で最大の長方形を求める」という古典的な問題を応用することで効率的に解くことができます。手順は以下の通りです。1行目をそのままヒストグラムとみなし、スタックを使って最大長方形の面積を計算します。2行目以降では、現在のセルが1であれば、直前の行の同じ列の値に加算します。これにより、各列につい
-
C++で二分木の2番目に小さいノードの値を求める方法
本記事では、特殊な二分木(バイナリツリー)の中から2番目に小さい値を見つけるアルゴリズムを、C++のコード例とともにわかりやすく解説します。問題の概要次のような条件を満たす、空ではない特殊な二分木が与えられます。各ノードは「子を2つ持つ」か「子を1つも持たない」かのどちらかであるノードが2つの子を持つ場合、そのノードの値は必ず2つの子のうち小さい方の値と等しいつまり、root.val = min(root.left.val, root.right.val) という関係が常に成り立ちます。このような二分木が与えられたとき、木全体のすべてのノードの値からなる集合の中で2番目に小さい値を求めてくださ
-
C++で最長連続増加部分列(LCIS)の長さを求める方法
問題の概要 整数の配列が与えられたとき、最長連続増加部分配列(Longest Continuous Increasing Subsequence)の長さを求める問題を考えてみましょう。「連続増加」とは、隣り合う要素が単調に増加し続けている状態を指します。 例えば、入力が [2,4,6,5,8] の場合、出力は 3 になります。最も長い連続増加部分列は [2,4,6] であり、その長さが 3 であるためです。 アルゴリズムの考え方 この問題は、配列を一度だけ走査すれば解決できます。具体的な手順は次の通りです。 配列 nums のサイズが 1 以下の場合は、そのサイズをそのまま返します。 an