iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0
佛心分享-刷題不只是刷題

Leecode刷題系列 第 23

D24:Q130Surrounded Regions

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241013/20169309QMLt8dMMHL.png
這題要在一個 m x n 的棋盤上,找到被 'X' 圍住的區,並把區域裡的 'O' 轉成 'X',重點在區域的邊界條件,就是所有不能被包圍的 'O' 一定在邊界或跟邊界相連,所以,主要的問題就是怎麼有效的找到這些不該被改成 'X' 的 'O'。

想法:
拆問題,目標是改那些被 'X' 完全包住的 'O',但不能改跟邊界連在一起的 'O',因為這些 'O' 沒辦法被包圍所以可以從邊界開始,找跟邊界相連的 'O',把它們標成不能改。

深度優先搜尋 (DFS) 或廣度優先搜尋 (BFS),從邊界開始,對每個 'O' 搜索,把所有跟邊界相連的 'O' 標成另外的符號(例如 '#'),這樣就不會誤修改,雙重遍歷,遍歷整個棋盤,把所有剩下的 'O'(沒被標記的 'O')改成 'X',因為這些 'O' 是被包起來的,再把標記的 '#' 恢復成 'O',邊界情況,要注意處理棋盤大小是 1x1 或非常長的棋盤,這些特例可能出現錯誤結果,所以一定要設好邊界條件。
步驟:
從棋盤的四條邊出發,找出所有跟邊界相連的 'O',用 DFS 或 BFS 遍歷這些邊界的 'O' 然後標記,遍歷整個棋盤,把那些沒標記的 'O' 改成 'X',然後把標過的 'O' 恢復成 'O'。
心得:
這題主要考圖的遍歷技術跟對邊界情況的考慮,尤其是深度優先或廣度優先的應用,當棋盤增大,這種搜索方法依然能高效運行,這讓我更理解 DFS 和 BFS 的用途,對邊界條件和特殊情況的處理技巧也有進步(我自己覺得啦),對之後的圖論問題處理比較有自信。
程式碼:
class Solution(object):
def solve(self, board):
"""
:type board: List[List[str]]
:rtype: None Do not return anything, modify board in-place instead.
"""
if not board or not board[0]:
return

    #取得行數、列數
    rows, cols = len(board), len(board[0])
    
    #定義一個深度優先搜尋函數
    def dfs(r, c):
        # 如果當前點超出邊界或不為是'O',直接返回
        if r < 0 or r >= rows or c < 0 or c >= cols or board[r][c] != 'O':
            return
        #標記當前的 'O',暫時用 '#' 表不被修改
        board[r][c] = '#'
        #遞迴搜尋四個方向
        dfs(r + 1, c)  # 向下
        dfs(r - 1, c)  # 向上
        dfs(r, c + 1)  # 向右
        dfs(r, c - 1)  # 向左

    #從邊界的 'O' 開始深度優先搜尋,標記跟邊界相連的 'O'
    for i in range(rows):
        dfs(i, 0)        # 第一列
        dfs(i, cols - 1) # 最後一列
    for j in range(cols):
        dfs(0, j)        # 第一行
        dfs(rows - 1, j) # 最後一行
    
    #遍歷整個棋盤,把所有沒標記的 'O' 變成 'X'
    #同時把標記成 '#' 的恢復 'O'
    for i in range(rows):
        for j in range(cols):
            if board[i][j] == 'O':
                board[i][j] = 'X'  # 被包圍的 'O' 改 'X'
            elif board[i][j] == '#':
                board[i][j] = 'O'  # 邊界相連的 'O' 恢復

思路:
找出所有跟邊界相連的 'O',從邊界開始,對每個 'O' 深度優先搜索(DFS),把這些 'O' 標記成 #,表它們不該被轉換,遍歷棋盤修改,把所有沒標的 'O' 轉成 'X',因為這些 'O' 是被包圍的,然後把標記 # 的恢復成 'O'。

解釋:
DFS 遍歷,深度優先搜尋是解決這類「連通性」問題的重要技巧,這種問題通常會用到 DFS 或 BFS 來遍歷某個區域,處理邊界,因為任何跟邊界相連的 'O' 都不能被包圍,所以先從邊界出發用DFS,通過圖的遍歷解決「區域包圍」問題,且考慮邊界的處理,增強了圖論問題的實做能力。


上一篇
D23:Q120Triangle
下一篇
D25:Q132Palindrome Partitioning II
系列文
Leecode刷題28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言