LeetCode -- 1970. Last Day Where You Can Still Cross

更新 發佈閱讀 7 分鐘

核心概念

使用二分搜搭配 BFS。

利用二分搜天數,找到 "The last day where we can still cross"。當二分搜到的該天還有路可以走則繼續往後面的天數二分搜,若沒路可以走則往前面的天數二分搜。

舉個例子,假如是 3*3 的矩陣,會有九天需要確認。第一次檢查第五天是否有路可以走,如果有,則檢查第七或第八天 (取決於程式碼如何設計);如果沒有,則檢查第二或第三天 (取決於程式碼如何設計)

BFS 則是負責遍歷所有路徑。仔細來說就是,每一層迴圈都去查找一個 raw 中各元素的上下左右是否可以走 (檢查上方是因為可能可以往上繞)。

當然,其中還有一些小細節。例如,最基礎的邊界檢查;用 set 儲存走過的格子 (如果使用 Python),因為若 (1,1) (1,2) (1,3) 可走,(1,2) 會在檢查 (1,1) 右邊,(1,2)左邊後被新增兩次。至於用 set 是因為,set 在 Python 中是以 hashtable 形式建立,查詢是否重複時比較快;以及用遞迴實作 BFS 可能會 MLE。

程式碼執行流程

在 Solution class 中開另一個 canCross 函數處理 BFS。

在 latestDayToCross 函數中,變數 left, right 儲存二分搜的左界和右界。

執行 while 迴圈直到 left > right 或 left == right。接著,將中間值 (要檢查的天) 帶入 canCross 函數。如果回傳 True,則 left = mid + 1;如果回傳 False,則 right = mid。舉個例子,現在有 1, 2, 3, 4 天。其中,1 和 2 可以走,3 和 4 不行走。第一次 left = 1, right = 4, mid = 2;第二次 left = 3, right = 4, mid = 3 ; 第三次 left = 3, right = 3 結束。最後,回傳 right -1。減一是因為找到的那天是不能走的。

canCross 中,我們先將 cells 轉成 set 型態方便之後檢查。

變數 queue 用來儲存當前的位置,當要檢查格子時從左邊 pop 出來,達到先進先出(右進左出);visited 用來儲存走過的格子避免重複檢查。

對於矩陣的第一層,我們獨立檢察。如果不在 water 中,就新增進 queue 和 visited 中。至於為什麼用 tuple 來儲存 r 和 c,是因為 tuple is hashable,換句話說,只有 tuple 可以新增進 set,其餘的像 list、dictionary 都不行。可能有人會看到除 add 還有一個 update 函式也可以新增資料,並且還可以將 list 當參數帶入,但新增進 set 的資料不會兩兩一對。

vocus|新世代的創作平台

這裡,我們舉個例子

vocus|新世代的創作平台

假如我們有一個 3*3 的矩陣,並且還在第一天的狀態。此時,當我們的程式碼檢查完第一層矩陣後 queue = [(0,0), (0,2)], visited = [(0,0), (0,2)]

接著往下走是 BFS 的 while 迴圈。這裡,我們執行到 queue 沒有東西為止

我們從 queue 中的最左邊開始取,並用 r 和 c 來存。如果 r == row - 1,代表我們已經到最後一個 row,檢查完畢,這天還是有路可以走的,回傳 True。如果還沒走到最後,則去檢查剛剛取出那點的上下左右是否可以走

以下是完整的程式碼

from collections import deque

class Solution:
    def canCross(self, day: int, row: int, col: int, cells: list) -> bool:
        # 建立第 day 天的水域
        water = set()
        for i in range(day):
            water.add((cells[i][0]-1, cells[i][1]-1))
        # BFS
        queue = deque()
        visited = set()
        for c in range(col):
            if (0, c) not in water:
                queue.append((0, c))
                visited.add((0, c))
        while queue:
            r, c = queue.popleft()
            if r == row - 1:
                return True
            for dr, dc in [(1,0), (-1,0), (0,1), (0,-1)]:
                nr, nc = r + dr, c + dc
                if (0 <= nr < row and 0 <= nc < col
                    and (nr, nc) not in water
                    and (nr, nc) not in visited):
                    visited.add((nr, nc))
                    queue.append((nr, nc))
        return False

    def latestDayToCross(self, row: int, col: int, cells: list) -> int:
        left, right = 1, (row*(col-1))+1
        while left < right and left != right:
            mid = (left + right ) // 2
            if self.canCross(mid, row, col, cells):
                left = mid + 1 # 還能走,試更晚的天數
            else:
                right = mid # 走不通,試更早的天數
        return left-1



留言
avatar-img
周濡墨的沙龍
20會員
121內容數
有別於未付費的文章,專題區的文章偏向愛情短篇小說,較有戲劇性,篇幅也會較長;未付費文章會偏向極短篇小說,並且以類似散文的手法寫作
周濡墨的沙龍的其他內容
2025/09/01
Description Given an m x n binary matrix mat, return the number of submatrices that have all ones. 給定一個 m x n 二進位矩陣 mat ,傳回全為 1 的子矩陣的數量。 Solution
Thumbnail
2025/09/01
Description Given an m x n binary matrix mat, return the number of submatrices that have all ones. 給定一個 m x n 二進位矩陣 mat ,傳回全為 1 的子矩陣的數量。 Solution
Thumbnail
2025/08/19
Description You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of thei
Thumbnail
2025/08/19
Description You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of thei
Thumbnail
2025/08/19
前言 為了完成 LeetCode 題目 2. Add Two Numbers,我特地學習了 Python 中的 Linked List。不過我花了大約一小時的時間翻閱中英文影片及文章,卻始終找不到滿意的解說。 於是,我請 AI 當我的老師,生成了一篇 Python Linked List 教學。
2025/08/19
前言 為了完成 LeetCode 題目 2. Add Two Numbers,我特地學習了 Python 中的 Linked List。不過我花了大約一小時的時間翻閱中英文影片及文章,卻始終找不到滿意的解說。 於是,我請 AI 當我的老師,生成了一篇 Python Linked List 教學。
看更多
你可能也想看
Thumbnail
寫程式是一件讓人感到害怕的一件事,但是寫程式真的對職場幫助很大,不管是邏輯思考或是資料處理,都讓我跟不會寫程式的人高度不一樣......
Thumbnail
寫程式是一件讓人感到害怕的一件事,但是寫程式真的對職場幫助很大,不管是邏輯思考或是資料處理,都讓我跟不會寫程式的人高度不一樣......
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
為什麼要學習程式呢? 程式是怎麼分類的? 能處理什麼事情?
Thumbnail
為什麼要學習程式呢? 程式是怎麼分類的? 能處理什麼事情?
Thumbnail
原本這次的徵文題目應該是「整座城市都在閱讀─我讀2021台北國際書展」,最後很可惜這個題目也被迫夭折。 不過實體無法做到的,就以數位實現,這本來就是方格子一直在做的事。所以即使書展取消了,閱讀也不曾/不該/不會停止。邀請格友們來分享你最近的購書清單…
Thumbnail
原本這次的徵文題目應該是「整座城市都在閱讀─我讀2021台北國際書展」,最後很可惜這個題目也被迫夭折。 不過實體無法做到的,就以數位實現,這本來就是方格子一直在做的事。所以即使書展取消了,閱讀也不曾/不該/不會停止。邀請格友們來分享你最近的購書清單…
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
我今天學到了一個應用程式,只要把自己想打得字打進去打進去,在設定自己喜歡的圖片,他就換幫你轉換成一種密密麻麻很酷的風格。這堂課讓我學到很多東西,也明白現在的科技做的事越來越多了~希望自己以後能更努力的學習
Thumbnail
我今天學到了一個應用程式,只要把自己想打得字打進去打進去,在設定自己喜歡的圖片,他就換幫你轉換成一種密密麻麻很酷的風格。這堂課讓我學到很多東西,也明白現在的科技做的事越來越多了~希望自己以後能更努力的學習
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
無論年紀多大多小,只要「願意」付出行動 時間、地點都不是問題 現在都有兒童程式課程 小朋友學的是利用積木組合而成的程式 大朋友就可以直接拿鍵盤來劈哩啪啦開始寫程式碼囉~
Thumbnail
無論年紀多大多小,只要「願意」付出行動 時間、地點都不是問題 現在都有兒童程式課程 小朋友學的是利用積木組合而成的程式 大朋友就可以直接拿鍵盤來劈哩啪啦開始寫程式碼囉~
Thumbnail
白晝的餘燼用酒澆熄 自愛情燃燒後 一壺傾倒的月光    漫過你的唇    輕吻沉醉的靈魂 這是你的城市 不是我的  我的城市在夜裡燃燒 自你走後 漫天紛飛的細雨                                                                  
Thumbnail
白晝的餘燼用酒澆熄 自愛情燃燒後 一壺傾倒的月光    漫過你的唇    輕吻沉醉的靈魂 這是你的城市 不是我的  我的城市在夜裡燃燒 自你走後 漫天紛飛的細雨                                                                  
Thumbnail
public class MultiplicationTable { public static void main(String[] args) { int size = 9; // 設定九九乘法表的大小 // 雙層迴圈用於生成九九乘法表 f
Thumbnail
public class MultiplicationTable { public static void main(String[] args) { int size = 9; // 設定九九乘法表的大小 // 雙層迴圈用於生成九九乘法表 f
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News