数据结构算法

一、回溯

知识点讲解

练习:

1、排列、组合、子集相关

提示:这部分练习可以帮助我们熟悉「回溯算法」的一些概念和通用的解题思路。解题的步骤是:先画图,再编码。去思考可以剪枝的条件, 为什么有的时候用 used 数组,有的时候设置搜索起点 begin 变量,理解状态变量设计的想法。

46.全排列(中等)
47.全排列 II(中等):思考为什么造成了重复,如何在搜索之前就判断这一支会产生重复;
39.组合总和(中等)
40.组合总和 II(中等)
216.组合总和III
77.组合(中等)
78.子集(中等)
90.子集 II(中等):剪枝技巧同 47 题、39 题、40 题;
60.第 k 个排列(中等):利用了剪枝的思想,减去了大量枝叶,直接来到需要的叶子结点;
93.复原 IP 地址(中等)
2、Flood Fill

提示:Flood 是「洪水」的意思,Flood Fill 直译是「泛洪填充」的意思,体现了洪水能够从一点开始,迅速填满当前位置附近的地势低的区域。类似的应用还有:PS 软件中的「点一下把这一片区域的颜色都替换掉」,扫雷游戏「点一下打开一大片没有雷的区域」。

下面这几个问题,思想不难,但是初学的时候代码很不容易写对,并且也很难调试。我们的建议是多写几遍,忘记了就再写一次,参考规范的编写实现(设置 visited 数组,设置方向数组,抽取私有方法),把代码写对。

733. 图像渲染(Flood Fill,中等)
200. 岛屿数量(中等)
130. 被围绕的区域(中等)
79. 单词搜索(中等)
3、字符串中的回溯问题

提示:字符串的问题的特殊之处在于,字符串的拼接生成新对象,因此在这一类问题上没有显示「回溯」的过程,但是如果使用 StringBuilder 拼接字符串就另当别论。
在这里把它们单独作为一个题型,是希望朋友们能够注意到这个非常细节的地方。

17-电话号码的字母组合(中等),题解;
784-字母大小写全排列(中等);
79-单词搜索
60-排列序列
332- 重新安排行程
22- 括号生成(中等) :这道题广度优先遍历也很好写,可以通过这个问题理解一下为什么回溯算法都是深度优先遍历,并且都用递归来写。
4、游戏问题
51. N 皇后(困难):其实就是全排列问题,注意设计清楚状态变量,在遍历的时候需要记住一些信息,空间换时间;
37. 解数独(困难):思路同「N 皇后问题」;
488. 祖玛游戏(困难)
529. 扫雷游戏(困难)

二、二分法

模版

def Bisection(nums):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) >> 1
        cur = nums[mid]
        if cur == target:
            return mid 
        elif cur <= target:
            left = mid + 1
        else:
            right = mid - 1
    return left
1.最大值最小化、最小值最大化类型题可以使用二分求解!!!

410.分割数组的最大值

三、优先队列

python中优先队列可以使用heapq或者queue.PriorityQueue()实现。

heapq.heapify(pq)
heapq.heappop(pq)
heapq.heappush(pq, target)
heapq.heapreplace(pq, target)

queue = queue.PriorityQueue()
queue.put()  # 往队列中加元素
queue.get()  # 往队列中删除元素
queue.empty() # 判断队列是否为空

1.单源最短路径问题
Python单源最短路径算法汇总
Python Leetcode网络延迟时间一题多解
Python 最短路径之存在某种限制条件下求最小值
Python Leetcode单源最短路径之两种权值下求解最小值

贝尔曼算法似乎是通用的算法?

743.网络延迟时间
787.K站中转内最便宜的航班
1928.规定时间内到达终点的最下花费
LCP 35. 电动车游城市

四、差分

1893、检查是否区域内所有整数都被覆盖

五、并查集

代码模板:

class UnionFind:
    def __init__(self, n):
        self.father = list(range(n))
        self.num_of_sets = n

    def find(self, i):
        if self.father[i] == i:
            return i
        self.father[i] = self.find(self.father[i]) # 具有路径压缩的功能
        return self.father[i]

    def is_connected(self, i, j):
        return self.find(i) == self.find(j)

    def merge(self, i, j):
        x, y = self.find(i), self.find(j)
        self.father[x] = y
        self.num_of_sets -= 1
547.省份数量
1202.交换字符串中的元素
1391.检查网格中是否存在有效路径
139.单词拆分

六、BFS

130. 被围绕的区域

双端BFS
代码模板:(127单词接龙)

class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        wordList = set(wordList)
        if endWord not in wordList:
            return 0
        first, second = {beginWord}, {endWord}
        dist = 1
        while first:
            dist += 1
            temp = set()
            for word in first:
                for i, w in enumerate(word):
                    for j in range(26):
                        cur_w = word[:i] + chr(ord('a') + j) + word[i + 1:]
                        if cur_w == w:
                            continue
                        if cur_w in second:
                            return dist
                        if cur_w in wordList:
                            temp.add(cur_w)
                            wordList.remove(cur_w)
            first = temp 
            if len(first) > len(second):
                first, second = second, first
        return 0

另外与之类似的题:

126.单词接龙II

七、字典树

模板

class Trie(object):
    def __init__(self):
        self.root = {}
        self.end_of_word = '#'
    
    def insert(self, word):
        node = self.root
        for char in word:
        	if char not in node: 
        		node[char] = {}
       		node = node[char]
        node[self.end_of_word] = self.end_of_word
	# 查找某个单词是否存在
    def search(self, word):
        node = self.root
        for char in word:
            if char not in node:
                return Fasle
            node = node[char]
        return self.end_of_word in node
    # 判读某个单词是否为一个前缀
    def starts_with(self, prefix):
        node = self.root
        for char in prefix:
            if char not in node:
                return Fasle
            node = node[char]
        return True

题型


648.单词替换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值