Pythonで1つの0を反転した後に得られる、連続する1の最長部分文字列の長さを求めるプログラム
バイナリ文字列 s が与えられたとします。「0」を「1」に反転できるのは最大1回までという条件のもとで、連続する「1」からなる最長の部分文字列の長さを求める必要があります。
例えば、入力が s = "1010110001" の場合、出力は 4 になります。インデックス3にある「0」を反転すると文字列は "1011110001" となり、このとき連続する「1」の最長部分文字列の長さが4になるためです。
解決アプローチ:スライディングウィンドウ
この問題はスライディングウィンドウ(2ポインタ)のテクニックを使うことで効率的に解けます。ウィンドウ内に含まれる「0」の数が1個以下である状態を保ちながら右端を伸ばし、条件を満たさなくなったら左端を縮めていくのがポイントです。
具体的な手順は以下の通りです。
n:= 文字列sの長さans:= 0、ones:= 0、left:= 0、right:= 0 で初期化right < nの間、以下を繰り返す:s[right]が「1」なら、onesを1増やすright - left + 1 - ones > 1(ウィンドウ内の「0」が2個以上ある状態)の間、以下を繰り返す:remove:=s[left]removeが「1」なら、onesを1減らすleftを1増やす
ans:=ansと(right - left + 1)の最大値rightを1増やす
ansを返す
実装例
理解を深めるために、以下の実装例を見てみましょう。
def solve(s):
n = len(s)
ans = ones = left = right = 0
while right < n:
if s[right] == "1":
ones += 1
while right - left + 1 - ones > 1:
remove = s[left]
if remove == "1":
ones -= 1
left += 1
ans = max(ans, right - left + 1)
right += 1
return ans
s = "1010110001"
print(solve(s))入力
"1010110001"
出力
4
計算量について
各文字は左ポインタと右ポインタによってそれぞれ最大1回ずつ処理されるため、時間計算量は O(n)、追加のメモリ使用量は O(1) となります。文字列が非常に長い場合でも高速に動作するのがこの手法の大きな利点です。
-
Pythonで二分木の最長連続パスの長さを求めるアルゴリズムと実装
二分木(バイナリツリー)が与えられたとき、木の中にある最長の連続パスの長さを求めることを考えます。ここでの「連続パス」とは、隣り合うノードの値が1ずつ増加、または1ずつ減少していくようなノードの並びのことです。問題の例例えば、次のような二分木が入力として与えられたとします。この場合、最も長い連続シーケンスは [2, 3, 4, 5, 6] となるため、出力は 5 になります。解き方のアプローチこの問題は、再帰的に各ノードを訪問しながら「増加パス」と「減少パス」の長さを追跡することで解けます。手順は以下の通りです。ルートがnullの場合は0を返す最大パス長を記録する変数 maxPath を0で初
-
Pythonで二分木の最長交互パス(ジグザグパス)の長さを求めるプログラム
問題概要 二分木が与えられたとき、「左の子 → 右の子 → 左の子…」のように左右交互にたどりながら下へ進む最長のパス(交互パス)の長さを求めます。 例として、次のような二分木が入力されたとします。 この場合、交互パスは [2, 4, 5, 7, 8] となるため、出力は 5 になります。 解き方のステップ この問題を解くには、以下の手順に従います。 ルートが null(空)の場合は 0 を返します。 dfs() 関数を定義します。この関数は node(現在のノード)、count(現在のパス長)、flag(次に進むべき方向)を引数に取ります。 node が null でない場合: f