📌  相关文章
📜  字典序最小和最大含有另一个字符串作为其子字符串的字谜(1)

📅  最后修改于: 2023-12-03 14:53:25.748000             🧑  作者: Mango

字典序最小和最大含有另一个字符串作为其子字符串的字谜

该问题可以归类为字符串问题。给定一个字符串,需要在给定的字谜中找到一个字谜,使得该字谜含有给定字符串作为子串,并且字典序最小或最大。

解法
1. 基本解法

一种基本的解决方案是首先查找所有包含给定字符串的字谜,然后再从这些子字符串中找到字典序最小或最大的字谜。这个方法的缺点在于它需要去查找所有的子字符串,并且可能会产生较大的复杂度。

2. Trie树

Trie树是一种树型数据结构,用于快速检索给定的键值。它的基本思路是将每个字符串分解成字符的序列,并在树上遍历这个序列,直到达到字符串的末尾。Trie树的优点是它可以在O(L)的时间内检索长度为L的任何字符串。

因此,在这个问题中可以在Trie树中存储每个字谜的字符串。然后,我们可以遍历给定字符串的字符序列,并往下查找每个字符的子节点,如果不存在,则说明没有含有该字符串的字谜。 如果存在,则我们可以继续往下遍历,并将包含给定字符串的所有字谜保留下来,然后从中选择字典序最小或最大的字谜。

代码片段:

class TrieNode:
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.is_word = False
        self.word = ""
        
    def insert(self, word):
        node = self
        for w in word:
            node = node.children[w]
        node.is_word = True
        node.word = word
        
class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        # 将所有单词添加到 Trie 中
        trie = TrieNode()
        for word in words:
            trie.insert(word)

        m, n = len(board), len(board[0])
        visited = set()
        ans = []
        
        # dfs 搜索
        def helper(node, i, j):
            if node.is_word:
                ans.append(node.word)
                node.is_word = False
                
            for x, y in [[1,0],[-1,0],[0,1],[0,-1]]:
                _i, _j = i+x, j+y
                if not (0<=_i<m and 0<=_j<n) or ( _i, _j) in visited:
                    continue
                if board[_i][_j] not in node.children:
                    continue
                visited.add((_i, _j))
                helper(node.children[board[_i][_j]], _i, _j)
                visited.remove((_i, _j))
                
        # 根据 Trie 搜索
        for i in range(m):
            for j in range(n):
                if board[i][j] in trie.children:
                    visited.add((i, j))
                    helper(trie.children[board[i][j]], i, j)
                    visited.remove((i, j))
        
        return ans
总结

本题主要考察被搜索子串在字谜中的查询,和字谜的查找。我们可以使用基本搜索方法或者Trie树的方式来解决这个问题。

参考资料

Trie树

前缀树和AC自动机在字符串中的应用

返回的markdown格式如下:

# 字典序最小和最大含有另一个字符串作为其子字符串的字谜

该问题可以归类为字符串问题。给定一个字符串,需要在给定的字谜中找到一个字谜,使得该字谜含有给定字符串作为子串,并且字典序最小或最大。

## 解法

### 1. 基本解法

一种基本的解决方案是首先查找所有包含给定字符串的字谜,然后再从这些子字符串中找到字典序最小或最大的字谜。这个方法的缺点在于它需要去查找所有的子字符串,并且可能会产生较大的复杂度。

### 2. Trie树

Trie树是一种树型数据结构,用于快速检索给定的键值。它的基本思路是将每个字符串分解成字符的序列,并在树上遍历这个序列,直到达到字符串的末尾。Trie树的优点是它可以在O(L)的时间内检索长度为L的任何字符串。

因此,在这个问题中可以在Trie树中存储每个字谜的字符串。然后,我们可以遍历给定字符串的字符序列,并往下查找每个字符的子节点,如果不存在,则说明没有含有该字符串的字谜。 如果存在,则我们可以继续往下遍历,并将包含给定字符串的所有字谜保留下来,然后从中选择字典序最小或最大的字谜。

代码片段:

```python
class TrieNode:
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.is_word = False
        self.word = ""
        
    def insert(self, word):
        node = self
        for w in word:
            node = node.children[w]
        node.is_word = True
        node.word = word
        
class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        # 将所有单词添加到 Trie 中
        trie = TrieNode()
        for word in words:
            trie.insert(word)

        m, n = len(board), len(board[0])
        visited = set()
        ans = []
        
        # dfs 搜索
        def helper(node, i, j):
            if node.is_word:
                ans.append(node.word)
                node.is_word = False
                
            for x, y in [[1,0],[-1,0],[0,1],[0,-1]]:
                _i, _j = i+x, j+y
                if not (0<=_i<m and 0<=_j<n) or ( _i, _j) in visited:
                    continue
                if board[_i][_j] not in node.children:
                    continue
                visited.add((_i, _j))
                helper(node.children[board[_i][_j]], _i, _j)
                visited.remove((_i, _j))
                
        # 根据 Trie 搜索
        for i in range(m):
            for j in range(n):
                if board[i][j] in trie.children:
                    visited.add((i, j))
                    helper(trie.children[board[i][j]], i, j)
                    visited.remove((i, j))
        
        return ans
总结

本题主要考察被搜索子串在字谜中的查询,和字谜的查找。我们可以使用基本搜索方法或者Trie树的方式来解决这个问题。

参考资料

Trie树

前缀树和AC自动机在字符串中的应用