第169場周賽實錄(深度遍歷/廣度遍歷(bfs/dfs))

1306. 跳躍遊戲 III

難度:中等

這裏有一個非負整數數組 arr,你最開始位於該數組的起始下標 start 處。當你位於下標 i 處時,你可以跳到 i + arr[i] 或者 i - arr[i]。

請你判斷自己是否能夠跳到對應元素值爲 0 的 任意 下標處。

注意,不管是什麼情況下,你都無法跳到數組之外。

示例 1:

輸入:arr = [4,2,3,0,3,1,2], start = 5
輸出:true
解釋:
到達值爲 0 的下標 3 有以下可能方案:
下標 5 -> 下標 4 -> 下標 1 -> 下標 3
下標 5 -> 下標 6 -> 下標 4 -> 下標 1 -> 下標 3

示例 2:

輸入:arr = [4,2,3,0,3,1,2], start = 0
輸出:true
解釋:
到達值爲 0 的下標 3 有以下可能方案:
下標 0 -> 下標 4 -> 下標 1 -> 下標 3

示例 3:

輸入:arr = [3,0,2,1,2], start = 2
輸出:false
解釋:無法到達值爲 0 的下標 1 處。

提示:

  • 1 <= arr.length <= 5 * 10^4
  • 0 <= arr[i] < arr.length
  • 0 <= start < arr.length

解決方案 :

深度遍歷關鍵在於標記,意思是當向樹深度遍歷時,要記得對遍歷的位置進行標記防止反覆遍歷,當遍歷不下去時還需要記得刪除該標記,防止其他數分支訪問不到該節點,若無節點可訪問時,則返回false;若訪問到的節點符合條件時,則返回True。

class Solution:
    def dfs(self, arr, start, mark):
        print(start, arr[start])
        if arr[start] == 0:
            return True
        mark[start] += 1
        if 0 <= start - arr[start] < len(arr) and mark[start - arr[start]] == 0:
            if self.dfs(arr, start - arr[start], mark):
                return True
        if 0 <= start + arr[start] < len(arr) and mark[start + arr[start]] == 0:
            if self.dfs(arr, start + arr[start], mark):
                return True
        mark[start] -= 1
        return False
    
    def canReach(self, arr: List[int], start: int) -> bool:
        return self.dfs(arr, start, [0 for _ in range(len(arr))])

廣度遍歷與深度遍歷不同的是,除了要標記訪問的節點外,廣度遍歷重點是首先要設定一個數組,作爲廣度遍歷的源頭,且每次遍歷這個數組以廣度進行遍歷並更新這個數組,如果這個數組沒值時,則返回False

以下是網上某大神寫的廣度遍歷:

class Solution:
    def canReach(self, arr: List[int], start: int) -> bool:
        q, v, n = [start], {start}, len(arr)
        while q:
            p = []
            for i in q:
                if not arr[i]:
                    return True
                for j in i - arr[i], i + arr[i]:
                    if 0 <= j < n and j not in v:
                        p.append(j)
                        v.add(j)
            q = p
        return False

順帶附上該大神的深度遍歷,很便捷。

class Solution:
    def canReach(self, arr: List[int], start: int) -> bool:
        n, v = len(arr), set()
        def f(i):
            if not arr[i]:
                return True
            elif i not in v:
                v.add(i)
                return 0 <= i - arr[i] < n and f(i - arr[i]) or 0 <= i + arr[i] < n and f(i + arr[i])
        return f(start)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章