Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで操作を繰り返した後に得られる最大のバイナリ文字列を求めるプログラム

ここでは、あるバイナリ文字列(0と1だけで構成された文字列)が与えられたとき、次の2種類の操作を何回でも適用できるものとして、最終的に得られる数値として最大のバイナリ文字列を求める方法を解説します。

  • 文字列に部分文字列 "00" が含まれる場合、それを "10" に置き換えられる。
  • 文字列に部分文字列 "10" が含まれる場合、それを "01" に置き換えられる。

問題の例

たとえば入力が s = "001100" の場合、出力は 111011 になります。実際には、次のように文字列を変形できます。

(00)1100 → 101(10)0 → 1010(10) → 10(10)01 → 100(10)1 → 1(00)011 → 111011

解法のアプローチ

この問題は、各ステップを以下のように整理することで効率的に解けます。

  • length : 文字列 s の長さ
  • zeros : s に含まれる '0' の個数
  • zeros < 2 の場合、どの操作も数値を増やせないため、そのまま s を返す
  • s の先頭にある連続する '1' を取り除く
  • leading_ones : 取り除いた先頭の '1' の個数
  • leading_oneszeros - 1 を加算する(残りの 0 をほぼすべて 1 に変換できるため)
  • trailing_ones : 残りの部分に含まれる '1' の個数(length - leading_ones - 1)
  • answer_left : leading_ones 個の '1'
  • answer_right : trailing_ones 個の '1'
  • answer_left + "0" + answer_right を連結して返す

ポイントは、最終的な答えには 0 が最大でも 1 つしか残らないという点です。操作を組み合わせることで 0 を集めて 1 に変換でき、残った唯一の 0 は、先頭の 1 の並びの直後に配置するのが最適になります。

Pythonによる実装例

理解を深めるために、以下の実装を見てみましょう。

def solve(s):
    length = len(s)
    zeros = s.count('0')
    if zeros < 2:
        return s
    s = s.lstrip('1')
    leading_ones = length - len(s)
    leading_ones += zeros - 1
    trailing_ones = length - leading_ones - 1
    answer_left = '1' * leading_ones
    answer_right = '1' * trailing_ones
    return ''.join([answer_left, '0', answer_right])

s = "001100"
print(solve(s))

入力

"001100"

出力

111011

計算量について

このアルゴリズムは、文字列の走査とカウントのみで構成されているため、時間計算量は O(n)、空間計算量も結果の文字列生成を除けば O(1) です。文字列の長さが非常に大きい場合でも高速に動作します。

  1. Pythonで制約付きの建物の最大高さを求めるプログラム

    問題の概要整数 n と制約リスト restrictions が与えられたとします。私たちは都市に n 棟の新しい建物を一列に建てようとしていますが、高さに関するいくつかの制限があります。建物には左から順に 1 から n までの番号が付けられており、各制約は restrictions[i] = (id_i, max_height_i) の形式で表され、「id_i 番の建物の高さは max_height_i 以下でなければならない」ことを意味します。建物の高さに関する都市の規則は以下のとおりです。各建物の高さは 0 以上でなければなりません。1 番の建物(最初の建物)の高さは必ず 0 です。隣接す

  2. Pythonで二分木の各レベルの最大幅を求めるプログラム

    二分木が与えられたとき、ツリー内の任意のレベルにおける最大幅を求めることを考えます。ここでいう「レベルの幅」とは、そのレベルにおいて最も左端にあるノードと最も右端にあるノードの間に含まれるノード数のことです。例えば、次のような二分木が入力として与えられた場合を考えてみましょう。この場合、出力は 2 となります。解決のための手順この問題を解くために、以下の手順に従います。各深さにおける位置の最小値と最大値を保持するマップ d を作成します。初期値は、最小値を無限大(∞)、最大値を 0 とします。関数 dfs() を定義します。この関数は引数として root、pos := 0、depth := 0