[每日一題] 79. Word Search

題目描述

本題難度:Mediumjavascript

作題日期:2017年3月24日java

本題地址: leetcode.com/problems/wo…算法

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 cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.複製代碼

題目分析

題意是要求咱們求一個 MxN 的二位字母表中尋找是否有知足給定單詞的字母集合,限制條件是字母集合是相鄰的。數組

這道題的特別之處在於:起始位置不肯定 和 方向不定。通常的二維矩陣題目,都會給定一個起始位置,好比從左上角開始;也會限制搜索的方向,好比只能向右和向下走。學習

因爲起始位置不定,因此咱們須要輪詢二維數組的全部字母。方向不定,因此咱們在暴力搜索的時候,須要考慮邊界限制條件。優化

例子分析

假設咱們要在以下的二維數組中,尋找 SAD 字符串 是否符合條件。以下圖一spa

假設咱們已經肯定了起始點爲 S ,其位置座標是(1, 0) 。此時,咱們須要判斷字符S(1,0) 周邊是否有第二個字符A,此時有四個能夠選擇路徑:3d

  1. 向右走
    字符是 F(1, 1) ,不符合要求,捨棄
  2. 向上走
    字符是 A(0, 0),符合要求
  3. 向下走
    字符串 A(2, 0),符合要求,但因爲條件 2 已經知足了,須要繼續遞歸
  4. 向右走
    超過了邊界限制,不符合要求

在上一個步驟,咱們已經肯定了 SA ,接下來肯定 D。 其狀態以下圖二所示code

根據上一個步驟的分析,在 A(0, 0) 咱們也有四個選擇:cdn

  1. 向右
    B(0, 1) 不等於 D ,排除
  2. 向上
    越界了,不符合要求,排除
  3. 向下
    S(1, 0) 已經訪問過了,也應該排除
  4. 向左
    越界了,不符合要求,排除

在上面的分析中的第3步,咱們須要排除已經訪問過的字符,不然會進入死循環,這樣也會重複的選擇字符,不符合題目要求。

向上走的路徑不符合條件後,咱們須要回溯到上一個起始點,也就是 S(1, 0) 位置,從新選擇路徑3:向下走 。

重複最早的分析,咱們能夠獲得 SAD 是存在的,因此結果返回 True。

小結

從上面的分析,咱們在寫代碼的過程當中,須要注意以下幾點

  1. 注意數組越界的問題
  2. 若是當前位置的字母不知足條件,須要回溯到上一個起始點的字母
  3. 須要記錄下訪問的路徑,防止重複訪問節點

解題思路

暴力方法

用一個MxN數組 check 來標示訪問路徑,防止重複訪問,默認值是 false。當遍歷到位置(i,j) 的時候,將對應的 check[i][j] 設置成 true,代表該位置已經訪問過了,回溯後須要重置,將 check[i][j] 設置成 false。

時間複雜度是 O(MN4^K), 空間複雜度是 O(M*N)

優化空間

在上一個解題思路中,咱們用了一個二維數組 check 來保存搜索路徑,其空間複雜度是 O(MN)。實際上是沒有必要的,咱們在搜索到(i, j) 的時候,將對應的 board[i][j] 設置成 *,並將原值保存在一個 temp 變量中,在回溯後在恢復 board[i][j] 的值: board[i][j] = temp。

更好的方案是用二進制操做 異或 的特性: X^Y = Z 必定有 Z^Y = X , 詳見最佳提交。

時間複雜度是 O(MN4^K), 空間複雜度是 O(1)

最佳提交

總結

  1. 可使用數組(好比二維數組)保存訪問過的節點,這樣能夠防止重複訪問節點
  2. 空間優化的技巧:異或操做
  3. 回溯的時候須要重置路徑值

關於咱們

每日一道算法題是一個純粹的算法學習社區:經過天天一塊兒作一道算法題來提高咱們的算法能力。

每日一題算法羣如今一共有3000位小夥伴:有來自北美和國內頂尖名校的本科生、研究生和博士生;也有來自國內外各大互聯網公司(Google, Facebook, 亞馬遜, 百度, 阿里, 騰訊等)的經驗豐富的開發者。你們彙集只爲一個目的:天天一塊兒學習算法!

咱們堅信:學習算法是一種信仰!

長按下面的二維碼,關注每日一道算法題公衆號,跟咱們一塊兒學習算法!

相關文章
相關標籤/搜索