[LeetCode]79. Word Search

79. Word Search

题意:判断某个字符串是否按照数组中相邻的顺序,同时同一个位置的字符不能使用两次。

个人觉得这道题真的非常回溯,很典型的回溯思想。

回溯

思路:先遍历找到起始字符,然后利用回溯来确定是否符合题目条件,因为题目要求不能重复使用,所以我用一个set来纪录使用过的字符的坐标。

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        def backtracking(i, j, index, cur, visited):
            if index == len(word)-1:
                if (i, j) not in visited and cur + board[i][j] == word:
                    return True
                return False
            if (i, j) not in visited and i < len(board)-1 and board[i+1][j] == word[index+1] and backtracking(i + 1, j, index + 1, cur + board[i][j], visited|{(i, j)}):
                return True
            if (i, j) not in visited and i > 0 and board[i-1][j] == word[index+1] and backtracking(i - 1, j, index + 1, cur + board[i][j], visited|{(i, j)}):
                return True
            if (i, j) not in visited and j < len(board[0])-1 and board[i][j+1] == word[index+1] and backtracking(i, j + 1, index + 1, cur + board[i][j], visited|{(i, j)}):
                return True
            if (i, j) not in visited and j > 0 and board[i][j-1] == word[index+1] and backtracking(i, j - 1, index + 1, cur + board[i][j], visited|{(i, j)}):
                return True
            return False
        if not board or not word:
            return False
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j] == word[0] and backtracking(i, j, 0, '', set()):
                    return True
        return False

迭代版本

原本打算路径使用字符来纪录,但是因为只有坐标才能纪录它的唯一性,所以只能使用坐标。

import collections
class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        if not board or not word:
            return False
        mapping = collections.defaultdict(list)
        for i in range(len(board)):
            for j in range(len((board[0]))):
                mapping[board[i][j]].append((i, j))
        # 去除条件
        for key, value in collections.Counter(word).items():
            if len(mapping[key]) < value:
                return False
        path = []
        visited = set()
        stack = [(None, (i, j), 0) for i, j in mapping[word[0]]]
        while stack:
            pre, (i, j), idx = stack.pop()
            if idx == len(word)-1:
                return True
            # 回溯
            while path and path[-1] != pre:
                visited -= {path.pop()}
            path += (i, j),
            visited |= {(i, j)}
            stack.extend([((i, j), (x, y), idx+1) for x, y in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)] if (x, y) in mapping[word[idx+1]] and (x, y) not in visited])
        return False
posted @ 2017-08-31 13:20  banananana  阅读(126)  评论(0编辑  收藏  举报