Leetcode:每日很多题+字典树&并查集&高级搜索

这篇博客介绍了LeetCode中关于字典树、并查集和高级搜索算法的应用,包括前缀树实现、岛屿数量计算、被围绕的区域处理,以及括号生成、N皇后问题、有效数独、单词接龙和滑动谜题等经典问题的解题思路和代码实现。
摘要由CSDN通过智能技术生成

第一章 字典树

字典树的基本性质
在这里插入图片描述
核心思想
在这里插入图片描述

1、Leetcode 208:实现前缀树

题目描述
在这里插入图片描述

解题思路
相对而言比较简单,结构为集合套集合。具体步骤解释在代码中。

代码实现

class Trie:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        #定义一个tree,以字典的形式
        self.look_up={
   }

    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        
        """
        tree=self.look_up
        #遍历单词中出现的字母
        for char in word:
            #如果当前层没有该字母
            if char not in tree:
                #建立当前层字母的子树
                tree[char]={
   }
                #位置移动到下一层
            tree=tree[char]
        #在最后加上停止符号
        tree["#"]="#"

    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        tree=self.look_up
        #遍历单词中的字母
        for char in word:
            #如果当前字母不在树中:
            if char not in tree:
                return False
            #如果在,下移一层
            tree=tree[char]
        #遍历结束后,必须有"#"才可以
        return True if "#" in tree else False

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        #与search唯一的区别是不需要考虑有没有"#"
        tree=self.look_up
        for char in prefix:
            if char not in tree:
                return False
            tree=tree[char]
        #如果遍历完preflix没有返回False,返回True
        return True

2、Leetcode 212:单词搜索

题目描述
在这里插入图片描述

解题思路

  • 前缀树储存单词信息
  • 递归的方式遍历整个棋盘。

代码实现

class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        #step 1:建立前缀树
        root={
   }
        #遍历所有词
        for word in words:
            p=root
            #遍历所有字母:
            for char in word:
                if char not in p:
                    p[char]={
   }
                #往下移动一层
                p=p[char]
            #标记每个单词
            p["finish"]=word
        #step 2:建立递归函数
        m=len(board)
        n=len(board[0])
        res=[]
        def dfs(start,p):
            #定位到坐标
            i,j=start[0],start[1]
            #定位到坐标值
            c=board[i][j]
            #查看该字母在不在树中,同时查看它到达这个位置后是否有finish
            #且将已经查看过的词的节点直接删除掉。
            last=p[c].pop("finish",False)
            #如果有finish
            if last:
                #将词添加
                res.append(last)
            #开始移动该点
            board[i][j]="#"
            #s四个方向
            for x,y in [(1,0),(0,1),(-1,0),(0,-1)]:
                new_i=i+x
                new_j=j+y
                #判断是否符合要求
                if 0<=new_i<m and 0<=new_j<n and board[new_i][new_j] in p[c]:
                    #进入下一层递归
                    dfs((new_i,new_j),p[c])
            #结束递归后,把值变回来
            board[i][j]=c
            
            if not p[c]:
                p.pop(c)
            
        #开始遍历board
        for i in range(m):
            for j in range(n):
                if board[i][j] in root:
                    dfs((i,j),root)
        return res

第二章 并查集

适用场景
组团和配对
基本操作

  • 创建一个新的并查集
  • 把元素x和y所在的集合合并,要求x和y所在的集合不相交,相交则不合并
  • 找到元素x所在的集合的代表,也可以判断两个元素是否位于同一个集合
    在这里插入图片描述
    在这里插入图片描述

1、Leetcode 200: 岛屿数量

解题思路

  • 建立并查集
  • 遍历grid,对于每个位置为1得查看他上下左右的值,如果也为1,那么通过并查集联合他们到一起
  • 问题:self.rank是做啥的。。发现把它删掉以后并不影响,所以删掉吧哈哈。

代码实现

#并查集
class UnionFind:
    def __init__(self,grid):
        #统计grid得长宽
        m,n=len(grid),len(grid[0])
        #计数变量
        self.count=0
        #并查集
        self.parent=[-1]*(m*n)
        self.rank=[0]*(m*n)
        #对于grid得每个点都建立一个初始集合,统计grid中值为1的数量
        for i in range(m):
            for j in range(n):
                if grid[i][j]=="1":
                    self.parent[i*n+j]=i*n+j
                    self.count+=1
    def find(self,i):
        #根的话会指向自己
        if self.parent[i]!=i:
            #通过递归不断去查找
            self.parent[i]=self.find(self.parent[i]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值