Skip to main content
Ctrl+K

Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges

  • Introduction: Navigating the Coding Cosmos
  • Chapter 1: Array Hashing
    • 100: Same Tree
    • 128. Longest Consecutive Sequence
    • 217. Contains Duplicate
    • 238. Product of Array Except Self
    • 242. Valid Anagram
    • 347. Top K Frequent Elements
    • 49. Group Anagrams
    • 659· Encode and Decode Strings
  • Introduction to Two Pointers Technique Challenges
    • 11. Container With Most Water
    • 125. Valid Palindrome
    • 15. 3Sum
  • Introduction to Sliding Window Challenges
    • 121. Best Time to Buy and Sell Stock
    • 3. Longest Substring Without Repeating Characters
    • 424. Longest Repeating Character Replacement
    • 76. Minimum Window Substring
  • Introduction to Stack Challenges: Unveiling Valid Parentheses
    • 20. Valid Parentheses
  • Introduction to Binary Search Challenges
    • 153. Find Minimum in Rotated Sorted Array
    • 33. Search in Rotated Sorted Array
  • Introduction to Linked List Mastery
    • 141. Linked List Cycle
    • 143. Reorder List
    • 19. Remove Nth Node From End of List
    • 206. Reverse Linked List
    • 21. Merge Two Sorted Lists
    • 23. Merge k Sorted Lists
  • Introduction to Tree Challenges
    • 100: Same Tree
    • 102. Binary Tree Level Order Traversal
    • 104. Maximum Depth of Binary Tree
    • 105. Construct Binary Tree from Preorder and Inorder Traversal
    • 124. Binary Tree Maximum Path Sum
    • 199. Binary Tree Right Side View
    • 226: Invert Binary Tree
    • 230. Kth Smallest Element in a BST
    • 235. Lowest Common Ancestor of a Binary Search Tree
    • 297. Serialize and Deserialize Binary Tree
    • 572: Subtree of Another Tree
    • 98. Validate Binary Search Tree
  • Unveiling the Power of Tries: A Journey in Prefix Trees
    • 208. Implement Trie (Prefix Tree)
    • 211. Design Add and Search Words Data Structure
    • 212. Word Search II
  • Unveiling the Power of Heaps and Priority Queues
    • 1046. Last Stone Weight
    • 295. Find Median from Data Stream
    • 703. Kth Largest Element in a Stream
  • Introduction to Backtracking Challenges
    • 39. Combination Sum
    • 79. Word Search
  • Introduction to Graph Challenges
    • 133. Clone Graph
    • 178. Graph Valid Tree
    • 200. Number of Islands
    • 207. Course Schedule
    • 3651. Number of Connected Components in an Undirected Graph
    • 417. Pacific Atlantic Water Flow
  • Introduction to Advanced Graphs: Navigating the Alien Dictionary
    • 892. Alien Dictionary
  • 1-D Dynamic Programming Problems - Blind 75 LeetCode
    • 70. Climbing Stairs
    • House Robber
    • House Robber II
  • Blind 75 LeetCode Problems
  • Blind 75 LeetCode Problems
  • Blind 75 LeetCode Problems
  • Blind 75 LeetCode Problems
  • Blind 75 LeetCode Problems
  • Repository
  • Open issue
  • .ipynb

79. Word Search

Contents

  • Probelm Explanation:
  • Solution:
  • Explanation:
  • Test cases:
  • Time and Space Complexity Analysis
  • Challenging Exercises:

79. Word Search#

Difficulty: Medium

Link to Problem: To see the Word Search problem on LeetCode, click here!


Given an m x n grid of characters board and a string word, return true if 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.

Constraints:

  • m == board.length

  • n = board[i].length

  • 1 <= m, n <= 6

  • 1 <= word.length <= 15

  • board and word consists of only lowercase and uppercase English letters.

Follow up: Could you use search pruning to make your solution faster with a larger board?

Probelm Explanation:#

The problem is to determine whether a given word can be constructed from characters in an m x n grid of characters. The word can be formed by moving sequentially through horizontally or vertically neighboring cells in the grid, and you cannot use the same cell more than once.

Here are the specifics of the problem:

  • You are given an m x n grid, which is a 2D board of characters.

  • You are also given a string word consisting of lowercase and uppercase English letters.

  • Your task is to determine if the word can be found in the grid by moving from one cell to an adjacent cell (horizontally or vertically) and collecting the characters sequentially to form the word.

  • You can’t use the same cell more than once when forming the word.

  • If it’s possible to form the word in the grid, return True; otherwise, return False.

For example, consider the following grid and word:

board = [["A", "B", "C", "E"],
         ["S", "F", "C", "S"],
         ["A", "D", "E", "E"]]         
word = "ABCCED"

In this case, the word “ABCCED” can be formed by moving through the cells (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) in the grid. Therefore, the function should return True.

Conversely, if the word is impossible to construct, such as in the case of the word “ABCB” for the same grid, where there’s no valid path that forms the word, the function should return False.

The problem involves searching for a path through the grid that matches the characters in the word while respecting the constraints mentioned. It can be solved using depth-first search (DFS) or backtracking.

Solution:#

Here’s a Python function to implement this algorithm:

from typing import List

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        def dfs(i, j, k):
            # Check if the current position is out of bounds or doesn't match the character in the word.
            if not (0 <= i < len(board)) or not (0 <= j < len(board[0])) or board[i][j] != word[k]:
                return False
            
            # If we have matched all characters in the word, return True.
            if k == len(word) - 1:
                return True

            # Temporarily mark the current cell to prevent revisiting.
            tmp, board[i][j] = board[i][j], "/"

            # Explore adjacent cells by making recursive calls in all four directions.
            found = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)

            # Restore the original character in the cell.
            board[i][j] = tmp

            return found

        # Iterate through all cells in the board.
        for i in range(len(board)):
            for j in range(len(board[0])):
                # Check if the 'dfs' function starting from this cell returns True.
                if dfs(i, j, 0):
                    return True

        # If no match is found after exploring all cells, return False.
        return False

Explanation:#

  1. Import the necessary module:

    • from typing import List: This line imports the List type from the typing module, which is used to specify the type of the board parameter in the method signature.

  2. Define the Solution class:

    • class Solution:: This line defines a class called Solution to encapsulate the solution for the word search problem.

  3. Define the exist method:

    • def exist(self, board: List[List[str]], word: str) -> bool:: This method is a member of the Solution class and takes two parameters: board, which is a 2D list of characters, and word, which is a string. It returns a boolean value, indicating whether the word exists in the board.

  4. Implement the inner dfs function:

    • def dfs(i, j, k):: This is a helper function used for depth-first search (DFS). It is called recursively to explore the board and search for the word. It takes three parameters: i and j representing the current position on the board, and k representing the current index in the word string.

    • Inside dfs, it checks if the current position is out of bounds or if the character at the current position on the board does not match the character at the current index in the word. If either of these conditions is met, it returns False.

    • If k is equal to the length of the word minus one, it means we have successfully matched all characters in the word, so it returns True.

    • The function then temporarily replaces the character at the current position with a marker, “/”, to prevent revisiting the same cell. It then explores adjacent cells by making recursive calls in all four directions: up, down, left, and right. If any of these recursive calls return True, it propagates the True result up the call stack. After the exploration is complete, it restores the original character in the cell.

  5. Iterate through the board:

    • The outer loop iterates through all cells in the board using two nested loops. For each cell, it checks if the dfs function starting from that cell (with k initially set to 0) returns True. If it does, it means the word exists, so the method returns True.

  6. Return False:

    • If the loop completes without finding the word in the board, the method returns False.

To use this code, you can create an instance of the Solution class and call the exist method on that instance, passing the board and the word as arguments to check if the word exists in the board.

Test cases:#

Here’s how you can use this solution:

# Example 1: 

# Create an instance of the Solution class
solution = Solution()

# Test case 1: Word "ABCCED" can be found in the grid
board1 = [["A","B","C","E"],
          ["S","F","C","S"],
          ["A","D","E","E"]]
word1 = "ABCCED"
print(solution.exist(board1, word1))  # Expected output: True
True
# Example 2

# Test case 2: Word "SEE" can be found in the grid
word2 = "SEE"
print(solution.exist(board1, word2))  # Expected output: True
True
# Example 3

# Test case 3: Word "ABCB" cannot be found in the grid
word3 = "ABCB"
print(solution.exist(board1, word3))  # Expected output: False
False

Time and Space Complexity Analysis#

Let’s analyze the time and space complexity of the exist method in the given code.

Time Complexity:

The primary work in this code is done by the dfs function, which performs a depth-first search through the grid. The time complexity of the dfs function is \(O(4^(n))\), where “n” is the length of the word. This is because, in the worst case, the function explores all possible directions (up, down, left, right) for each character in the word.

The outer loops iterate through all cells in the board, which has dimensions m x n. So, the total number of iterations of dfs is O(m * n). However, since the dfs function has a higher time complexity, the overall time complexity is still dominated by the dfs function.

Therefore, the overall time complexity of the exist method is \(O(m * n * 4^n)\), where “m” and “n” are the dimensions of the board, and “n” is the length of the word.

Space Complexity:

  1. The primary space usage comes from the recursive calls in the dfs function. The depth of the recursion can be at most equal to the length of the word, which is O(n).

  2. Additionally, the tmp variable and the recursive calls on the call stack consume a small amount of additional memory.

  3. The marking of visited cells with the “/” character temporarily modifies the board in-place but doesn’t significantly contribute to the space complexity.

Therefore, the overall space complexity is O(n) due to the recursive call stack.

In summary, the time complexity is \(O(m * n * 4^n)\), and the space complexity is O(n), where “m” and “n” are the dimensions of the board, and “n” is the length of the word. The time complexity is exponential in the worst case due to the depth-first search through all possible paths in the grid.

Challenging Exercises:#

  1. Optimization Challenge: Modify the code to find all unique words that can be constructed from the grid. Instead of returning True or False, return a list of words found. Ensure that the same cell is not used more than once in constructing each word.

  2. Board Generation: Create a function to generate random grids of characters and then use the exist method to solve them. Test the efficiency and correctness of your code by generating larger boards and words.

previous

39. Combination Sum

next

Introduction to Graph Challenges

Contents
  • Probelm Explanation:
  • Solution:
  • Explanation:
  • Test cases:
  • Time and Space Complexity Analysis
  • Challenging Exercises:

By Mohsen Tabibian and Saeed Samadidana

© Copyright 2022.