運動の[Leetcodeシリーズ] [] [中]アルゴリズムロボット範囲(BFS、DP)

トピック:

トピックリンク:  https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

 

問題解決のアイデア:

以下に示すように、開始領域から移動するには、連続していない場合、ロボットが行くことができない、行の0,0の点でなければならない。問題は、暗黙の条件があります

ロボットは直接イエローゾーンから、レッドゾーンに飛んだことはできません

これは、すべての計算された領域のすべての数字の和がにkよりも小さい、直接ではありません

 

方法:BFS(時間O(MN)、スペースO(MN))

検索の先頭から0,0点を、現在のグリッドが検索を続けるための条件、現在のグリッド右とキューにグリッドプットの下を満たすためにあれば、条件が満たされない場合、右と現在の格子グリッドの下には到達できない、ではありませんキューへのギャグ新しい子は、流れは以下の通り:

変数:

  1. キュー:キューが検索されるように、初期化のみ開始点(0,0)
  2. REC:対象は、空の最初に、キューを検索しました

プロセス:

まず、検索するキューに参加するには(0,0)ポイント:

数字0の和未満K = 2、(0,0)、RECに添加(0,0)と格子点0,0の右上側を探し続けました。

二つのセル(1,0)及び(0,1)内のキューは、RECに追加条件に沿って、数字1の和、、、右であり、検索トップに続けます。

方法2:DP(時間O(MN)、スペースO(N))

(0,0)は次のように、トラバース規則を各行を横断開始します。

  1. 電流がビットとkの数より大きい場合、続行
  2. グリッドの左と下のエッジが到達不能である場合、継続
  3. 他の例では、アップデートは、グリッド1を加え達することができます

実際には、我々は唯一のままにすることができ、現在の例事情を知っているし、格子グリッド格子を下げる必要があるため、dpの配列は、配列M×N個を作成する必要はありません、

なお、以下に示すように、フロー条件を満たすように、1個のだけ* nはアレイを作成します。

ライン横断ポイントによってスタートラインから0,0

第二行を横断し続け、この時間は、最初の行のアレイDP状態で格納され、トラバースは、値DP配列に対応する位置を決定する第二の行は最初の行が決定されている状態と等価です

それは第二のセルの2行目を判定された場合、以下のように、アレイDPの各要素の状態を表現しました:

  1. DP [0] = 1つの2細胞株
  2. DP [1] = 1つの2細胞株
  3. DP細胞の[2] = 1行3
  4. ...

したがって、第二のセル列2が決定される場合、それは唯一のDP決定される[0]、DP [1]、必要に応じて2の位置を決定することと等価です。

このロジックによると、完全なトラバーサルまで

 

コードの実装:

この方法の一つ:

import queue
class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        rec = queue.Queue()
        rec.put((0,0))
        res = set()
        while not rec.empty():
            x, y = rec.get()
            tmp = sum([int(a) for a in str(x)]) + sum([int(a) for a in str(y)])
            if tmp > k:
                continue
            elif x >= m or y >= n:
                continue
            elif (x, y) in res:
                continue
                
            res.add((x, y))
            rec.put((x + 1, y))
            rec.put((x, y + 1))
            
        return len(res)
                
            

 

方法2:

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        # 多创建一个位置,可以避免每次都进行越界检查
        rec = [0] * (n + 1)
        rec[1] = 1
        num = 0
        for x in range(m):
            # 如果上一行全部无法到达,本行也一定都无法到达,退出以提高效率
            if 0 == sum(rec):
                break
                
            for y in range(1, n + 1):
                tmp = sum([int(a) for a in str(x)]) + sum([int(a) for a in str(y - 1)])
                if tmp > k:
                    rec[y] = 0
                    continue
                    
                # 当前右值中的rec[y],就是下面一行是否可到达的值
                rec[y] = max(rec[y], rec[y - 1])
                if 1 == rec[y]:
                    num += 1

        return num

 

 

 

公開された100元の記事 ウォンの賞賛4 ビュー1463

おすすめ

転載: blog.csdn.net/songyuwen0808/article/details/105385537