​LeetCode刷題實戰79:單詞搜索

2021-03-02 程序IT圈

算法的重要性,我就不多說了吧,想去大廠,就必須要經過基礎知識和業務邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !

今天和大家聊的問題叫做 單詞搜索,我們先來看題面:

https://leetcode-cn.com/problems/word-search/

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cells, where "adjacent" cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

題意給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中「相鄰」單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重複使用。

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

給定 word = "ABCCED", 返回 true
給定 word = "SEE", 返回 true
給定 word = "ABCB", 返回 false

比如第一個字符串ABCCED,我們可以在數組當中找到這樣一條路徑:解題https://www.cnblogs.com/techflow/p/13180855.html題解如果你刷過許多題,經常思考的話,我想應該不難發現,這道題的本質其實和走迷宮問題是一樣的。我們拿到的這個二維的字符型數組就是一個迷宮, 我們是要在這個迷宮當中找一條「出路」。不過我們的目的不是找到終點,而是找到一條符合題意的路徑。在走迷宮問題當中,迷宮中不是每一個點都可以走的,同樣在當前問題當中,也不是每一個點都符合字符串的要求的。這兩個問題雖然題面看起來大相逕庭,但是核心的本質是一樣的。這個答案應該已經非常確定了,當然是搜索算法。我們需要搜索解可能存在的空間去尋找存在的解,也就是說我們面臨的是一個解是否存在的問題,要麼找到解,要麼遍歷完所有的可能性發現解不存在。確定了是搜索算法之後,剩下的就簡單了,我們只有兩個選項,深度優先或者是廣度優先。理論上來說,一般判斷解的存在性問題,我們使用廣度優先搜索更多,因為一般來說它可以更快地找到解。但是本題當中有一個小問題是,廣度優先搜索需要在隊列當中存儲中間狀態,需要記錄地圖上行走過的信息,每有一個狀態就需要存儲一份地圖信息,這會帶來比較大的內存開銷,同樣存儲的過程也會帶來計算開銷,在這道題當中,這是不可以接受的。拷貝狀態帶來的空間消耗還是小事,關鍵是拷貝帶來的時間開銷,就足夠讓這題超時了。所以我們別無選擇,只能深度優先。明確了算法之後,只剩下了最後一個問題,在這個走迷宮問題當中,我們怎麼找到迷宮的入口呢?因為題目當中並沒有規定我們起始點的位置,這也不難解決,我們遍歷二維的字符數組,和字符串開頭相匹配的位置都可以作為迷宮的入口。最後,我們來看代碼,並沒有什麼技術含量,只是簡單的回溯法而已。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        fx = [[0, 1], [0, -1], [1, 0], [-1, 0]]
        def dfs(x, y, l):
            if l == len(word):
                return True
            for i in range(4):
                nx = x + fx[i][0]
                ny = y + fx[i][1]
                # 出界或者是走過的時候,跳過
                if nx < 0 or nx == n or ny < 0 or ny == m or visited[nx][ny]:
                    continue
                if board[nx][ny] == word[l]:
                    visited[nx][ny] = 1
                    if dfs(nx, ny, l+1):
                        return True
                    visited[nx][ny] = 0
            return False
                
        n = len(board)
        if n == 0:
            return False
        m = len(board[0])
        if m == 0:
            return False
        
        visited = [[0 for i in range(m)] for j in range(n)]
        
        for i in range(n):
            for j in range(m):
                # 找到合法的起點
                if board[i][j] == word[0]:
                    visited = [[0 for _ in range(m)] for _ in range(n)]
                    visited[i][j] = 1
                    if dfs(i, j, 1):
                        return True
                    
        return False

總結如果能夠想通回溯法,並且對於回溯法的實現足夠熟悉,那麼這題的難度是不大的。實際上至今為止,我們一路刷來,已經做了好幾道回溯法的問題了,我想對你們來說,回溯法的問題應該已經小菜一碟了。相比於回溯法來說,我覺得更重要的是我們能夠通過分析想清楚,為什麼廣度優先搜索不行,底層核心的本質原因是什麼。這個思考的過程往往比最後的結論來得重要。好了,今天的文章就到這裡,如果覺得有所收穫,請順手點個在看或者轉發吧,你們的支持是我最大的動力。

相關焦點

  • ​LeetCode刷題實戰139:單詞拆分
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !題意給定一個非空字符串 s 和一個包含非空單詞的列表 wordDict,判定 s 是否可以被空格拆分為一個或多個在字典中出現的單詞。
  • LeetCode 79. 單詞搜索 | Python
    79.
  • ​LeetCode刷題實戰140:單詞拆分 II
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 單詞拆分 II,我們先來看題面:https://leetcode-cn.com/problems/word-break-ii/Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s
  • ​LeetCode刷題實戰81:搜索旋轉排序數組 II
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 搜索旋轉排序數組 II,我們先來看題面:https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/Suppose an array sorted in ascending order is rotated at some pivot
  • ​LeetCode刷題實戰33:搜索旋轉排序數組
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做搜索旋轉排序數組,我們先來看題面:https://leetcode-cn.com/problems/search-in-rotated-sorted-array/You are given an integer array nums sorted in ascending order, and an integer
  • ​LeetCode刷題實戰133:克隆圖
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !https://leetcode-cn.com/problems/clone-graph/Given a reference of a node in a connected undirected graph.
  • 帶你狂刷算法Leetcode題!短時間內快速獲得實戰能力!
    但對於初學者來說,很容易沉迷在刷題的數量中,覺得如果能刷完這1000道題,自己一定能夠有所飛躍。但實際上,低效率的重複對你來說,根本就無法掌握到解題的精髓,一旦題目有所變動,就無法舉一反三。那究竟應該怎麼刷題才高效呢?
  • ​LeetCode刷題實戰98:驗證二叉搜索樹
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 驗證二叉搜索樹,我們先來看題面:https://leetcode-cn.com/problems/validate-binary-search-tree/Given a binary tree, determine if it is a valid binary search tree (BST).
  • ​LeetCode刷題實戰68:文本左右對齊
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 文本左右對齊,我們先來看題面:https://leetcode-cn.com/problems/minimum-path-sum/Given an array of words and a width maxWidth, format the text such that each line has
  • ​LeetCode刷題實戰72:編輯距離
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 編輯距離,我們先來看題面:https://leetcode-cn.com/problems/edit-distanceGiven two words word1 and word2, find the minimum number of operations required to convert word1
  • ​LeetCode刷題實戰93:復原IP位址
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 復原IP位址,我們先來看題面:https://leetcode-cn.com/problems/restore-ip-addresses/Given a string s containing only digits, return all possible valid IP addresses that
  • ​LeetCode刷題實戰91:解碼方法
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 解碼方法,我們先來看題面:https://leetcode-cn.com/problems/decode-ways/A message containing letters from A-Z is being encoded to numbers using the following mapping
  • ​LeetCode刷題實戰36: 有效的數獨
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 有效的數獨,我們先來看題面:https://leetcode-cn.com/problems/valid-sudoku/Determine if a 9x9 Sudoku board is valid.
  • ​LeetCode刷題實戰198:打家劫舍
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 打家劫舍,我們先來看題面:https://leetcode-cn.com/problems/house-robber/You are a professional robber planning to rob houses along a street.
  • ​LeetCode刷題實戰42:接雨水
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 接雨水,我們先來看題面:https://leetcode-cn.com/problems/trapping-rain-water/Given n non-negative integers representing an elevation map where the width of each bar
  • ​LeetCode刷題實戰57:插入區間
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 插入區間,我們先來看題面:https://leetcode-cn.com/problems/insert-interval/Given a set of non-overlapping intervals, insert a new interval into the intervals (merge
  • ​LeetCode刷題實戰54:螺旋矩陣
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 螺旋矩陣,我們先來看題面:https://leetcode-cn.com/problems/spiral-matrix/Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in
  • ​LeetCode刷題實戰179:最大數
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 最大數  ,我們先來看題面:https://leetcode-cn.com/problems/largest-number/Given a list of non-negative integers nums, arrange them such that they form the largest number.
  • ​LeetCode刷題實戰70:爬樓梯
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 爬樓梯,我們先來看題面:https://leetcode-cn.com/problems/climbing-stairs/You are climbing a stair case.
  • leetcode刷題指南之findtheduplicatenumber
    給出一個長度為n+1的數組,其中每個數字的範圍是[1,n],其中只有一個重複的數,現在要求找出這個重複的數,並且滿足以下條件:不能改動原始數組除了原始數組,只能另外開闢O(1)的空間算法複雜度一定要小於O(n^2)重複的那個數可能重複不止一次初看這題可能有很多種方式