ESC
输入关键词搜索文章
目录

Leetcode

双指针

使用到的常见手段有:

回文链表

回文链表

移动零

移动零

盛最多水的容器

盛最多水的容器 盛最多水的容器 python 版 两侧交替移动指针。

三个数的和

由于不能有相同的结果,所以需要去重。 三个数的和

快慢指针 article

环形链表

(leetcode-solve-problem 141)
(leetcode-solve-problem 287)

哈希表

两数之和

两数之和

最长连续序列

最长连续序列 因为是连续序列,所以需要找到序列的起始处。

先把所有的数字加进列表,再一个个检查这些数字,到到其中的序列起始数字。从起始数字开始向上找,确定最长序列。

和为k 的子数组

(leetcode-solve-problem 567)

子数组

前缀和

将 “耗时的计算” 从 “每次查询时” 转移到 “查询前的准备阶段”,通过牺牲一定的空间复 杂度(存储预处理结果)来换取时间复杂度的降低(加速查询)。

新21点

和为 k 的子数组

(leetcode-solve-problem 567)

数学代码题

可能会使用到的手段有:

  1. 下界
  2. 等价

换水问题

换水问题

需要转换思路。

换水问题 2

换水问题2

不同路径

(leetcode-solve-problem 62)

子串

排序

排序的作用有以下几条:

  1. 方便去重
  2. 可以

但一般来说,如果想要应用排序,都需要保证输出结果里面不包括数字在数组中的排序,而只包括结果。

三位数的和

三位数的和

合并区间

带 key 的排序。 合并区间

拓扑排序

课程表

print(heapq.heappop(heap)) # 输出 1 #+end_src

注意:

快速排序

滑动窗口

最长无重复子串

最长无重复子串

找到字符串中所有的字母异位词

找到字符串中所有的字母异位词

滑动窗口最大值

滑动窗口最大值

有序列表、最小堆、双向队列,这道题总得用一种特殊数据结构。

单调栈

接雨水2

(leetcode-solve-problem 407)

最小堆

最小堆是一种特殊的完全二叉树,每个节点的值都小于或等于其子节点的值。根节点始终是树中的最小元素。

特点:

常见应用:

heapq

heapq 是 Python 内置的最小堆模块,提供基于列表的堆操作。

常用函数:

示例:

import heapq

heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
print(heapq.heappop(heap))  # 输出 1

注意:

数组中的第 k 个最大元素

heapq.heappush(heap, 2) print(heapq.heappop(heap)) # 输出 1 #+end_src

注意:

前 k 个高频元素

重构字符串

(leetcode-solve-problem 767)

接雨水2 transclusion

:END:

(leetcode-solve-problem 407)

线段树

最大子数组和

(leetcode-solve-problem 53)

爬楼梯

爬楼梯

矩阵

链表

链表相交

链表相交

反转链表

反转链表

回文链表

回文链表

(leetcode-solve-problem 141)
(leetcode-solve-problem 287)

环形链表 transclusion

(leetcode-solve-problem 141)
(leetcode-solve-problem 142)
(leetcode-solve-problem 287)

合并两个有序链表

(leetcode-solve-problem 21)

二叉树

二叉树的中序遍历

二叉树的中序遍历

二叉树的最大深度

二叉树的最大深度

翻转二叉树

(leetcode-solve-problem 141)
(leetcode-solve-problem 287)

对称二叉树

对称二叉树

先翻转,再对比是否相同。需要注意的是,不能从 root 开始翻转,不然就完全一样了。

二叉树的直径

(leetcode-solve-problem 543)

二叉树的层序遍历

(leetcode-solve-problem 102)

需要用到进行广度优先搜索

将有序数组转化为二叉搜索树

(leetcode-solve-problem 108)

图论

岛屿数量

岛屿数量

腐烂的橘子

腐烂的橘子

课程表

岛屿数量

水位上升的游泳池

(leetcode-solve-problem 794)

把所有的方格的高度与位置加进一个最小堆。

从列表里面逐一弹出方格,查看其四周是否有矮于它的方格,如果有,把自己加进它的集合。

每一次合并都需要检测,是不是左上与右下都在这个点内,如果是的话,那么就返回现在的这个方格的高度,否则还需要继续查找。

接雨水

接雨水

单词搜索

(leetcode-solve-problem 79)

回溯算法

全排列

全排列

(leetcode-solve-problem 794)

把所有的方格的高度与位置加进一个最小堆。

从列表里面逐一弹出方格,查看其四周是否有矮于它的方格,如果有,把自己加进它的集合。

每一次合并都需要检测,是不是左上与右下都在这个点内,如果是的话,那么就返回现在的这个方格的高度,否则还需要继续查找。

电话号码的字母组合

电话号码的字母组合

(leetcode-solve-problem 794)

把所有的方格的高度与位置加进一个最小堆。

从列表里面逐一弹出方格,查看其四周是否有矮于它的方格,如果有,把自己加进它的集合。

每一次合并都需要检测,是不是左上与右下都在这个点内,如果是的话,那么就返回现在的这个方格的高度,否则还需要继续查找。

括号生成

(leetcode-solve-problem 22)

完全平方数

(leetcode-solve-problem 322)

我本来想用 BFS 的回溯算法解决这道题。但是这道题有一个致命的问题,导致它不能用 BFS 回溯算法解决:每一次加进队列里面的项,它的键值(硬币数)是不一样的。

这就想当于本来每一次都是向下走一层,每一层都是一米,但现在每一次向下走的深度不一样了,有的层是两米,有的层是三米。 (leetcode-solve-problem 279)

标记变量

电话号码的字母组合 就是单纯地找到所有的组合。

所谓回溯算法就只是保存上一步的状态以方便恢复而已。

搜索

广度优先搜索

计算深度

腐烂的橘子

:END: 岛屿数量

深度优先搜索

二分查找

排序有着紧密的关系。

二分查找有两种实现方式,一种是递归,一种是循环。

递归二分查找

递归二分查找是一种通过函数自身调用来实现的二分查找算法。其核心思想是:

  1. 基本情况:当搜索区间为空(low > high)时返回 -1(未找到)
  2. 递归步骤
    • 计算中间位置 mid
    • 如果目标值等于中间元素,返回 mid
    • 如果目标值小于中间元素,在左半区间递归搜索
    • 如果目标值大于中间元素,在右半区间递归搜索

示例代码

def binary_search_recursive(arr, target, low, high):
    if low > high:
        return -1  # 未找到

    mid = (low + high) // 2

    if arr[mid] == target: # 基线条件
        return mid
    elif arr[mid] > target:
        return binary_search_recursive(arr, target, low, mid - 1) # 收缩范围
    else:
        return binary_search_recursive(arr, target, mid + 1, high)

特点

相比迭代版本,递归二分查找代码更简洁,但存在递归深度限制和额外的栈空间开销。

循环二分查找

循环二分查找通过 while 循环实现,避免了递归调用的栈空间开销。

/核心步骤/:

  1. 初始化 low = 0, high = len(arr) - 1
  2. 循环条件:low <= high
  3. 计算中间位置 mid
  4. 比较目标值与中间元素
  5. 根据比较结果调整搜索区间

/示例代码/:

def binary_search_iterative(arr, target):
    low, high = 0, len(arr) - 1

    while low <= high:
        mid = (low + high) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] > target:
            high = mid - 1
        else:
            low = mid + 1

    return -1  # 未找到

/特点/:

循环版本是实际应用中更常用的二分查找实现方式。

递归二分查找与循环二分查找的对比

特性 递归二分查找 循环二分查找
空间复杂度 O(log n) O(1)
时间复杂度 O(log n) O(log n)
代码简洁性 更简洁 稍复杂
性能 有递归开销 更高效
适用场景 教学、小数据量 生产环境、大数据量
溢出风险 : 可能(深度大时)

/关键区别/:

搜索插入位置

搜索二维矩阵

在排序数组中查找元素的第一个和最后一个位置

(leetcode-solve-problem 34)

二进制与位运算

子集

:ID: de03295d-7608-4a86-b7f5-aab378245f55 :END:

全排列

全排列

子集

子集

电话号码的字母组合

电话号码的字母组合 就是单纯地找到所有的组合。

所谓回溯算法就只是保存上一步的状态以方便恢复而已。

完全平方数

(leetcode-solve-problem 279)

只出现一次的数字

(leetcode-solve-problem 136) #+end_src

队列

括号生成

(leetcode-solve-problem 22)

最小栈

这道题的重点是需要想通:栈有着先进后出的特性。

所以,后进栈的元素如果比之前的最小元素还要大的话,那么这个新元素是不可能在某一个时刻中成为栈内的最小元素的。

我们之前遇到过滑动窗口最大值的问题,应该可以用类似的最小队列的方法来解决。用一个辅助队列来管理最大值,而后有一个定长队列一直进行着先进先出的流程;辅助队列中值的大小降序排列。如果出现一个更大的元素,就把这个元素之前的元素全部出队列。由此保证这个辅助队列从队头到队尾是依次降低的。

最小栈

字符串解码

每日温度

每日温度

贪心算法

什么是贪心算法?

贪心算法是一种在每一步选择中都采取当前状态下最优(即最有利)的选择,从而希望导致结果是全局最优的算法策略。

特点:

适用条件:

常见应用:

买卖股票的最佳时机

买卖股票的最佳时机

跳跃游戏

跳跃游戏 2

跳路游戏2

划分字母区间

划分字母区间

重构字符串

动态规划

动态规划(Dynamic Programming,简称 DP)是一种通过将复杂问题分解为重叠子问题,并 利用子问题的解来高效求解原问题的算法思想。它的核心是避免重复计算,通常用于解决具 有最优子结构和重叠子问题特性的问题。

将一个数字表示成幂的和的方案数 新21点 统计全为 1 的正方形子矩阵

多边形三角剖分的最低得分

多边形三角剖分的最低得分

接雨水

接雨水

最大子数组和 transclusion

(leetcode-solve-problem 53)

爬楼梯

爬楼梯

杨辉三角

打家劫舍

打家劫舍

完全平方数

:PROPERTIES: :ID: d6d65a94-54b8-43c2-8b49-c72c53214fa5

(leetcode-solve-problem 322)

我本来想用 BFS 的回溯算法解决这道题。但是这道题有一个致命的问题,导致它不能用 BFS 回溯算法解决:每一次加进队列里面的项,它的键值(硬币数)是不一样的。

这就想当于本来每一次都是向下走一层,每一层都是一米,但现在每一次向下走的深度不一样了,有的层是两米,有的层是三米。 (leetcode-solve-problem 279)

零钱兑换

:PROPERTIES: :ID: dc38566a-702c-4e29-b2ac-98b477c2de92

(leetcode-solve-problem 322)

我本来想用 BFS 的回溯算法解决这道题。但是这道题有一个致命的问题,导致它不能用 BFS 回溯算法解决:每一次加进队列里面的项,它的键值(硬币数)是不一样的。

这就想当于本来每一次都是向下走一层,每一层都是一米,但现在每一次向下走的深度不一样了,有的层是两米,有的层是三米。 (leetcode-solve-problem 279)

多维动态规划

子串

最小路径和

(leetcode-solve-problem 64)

子串

最长回文子串

(leetcode-solve-problem 5)

要想找到最长回文子串,必然需要两个指针,分别指向子串的头与尾。

也不一定。

从一个点出发,向两边延伸,看能延伸到多长,这也是一个思路。

对于回文子串类的问题,不能忘记有两种情况:一种是奇数长度回文子串,另一种是偶数长度。

对于一个回文子串,我们可以减小问题规模:只需要把回文子串的两端的值给去掉。如果这是一个回文子串,那么它去掉两端的值以后依然是。

最长公共子序列

(leetcode-solve-problem 1250)

重点在于不改变顺序

由于要求两者都按顺序取字母,可以减小问题的规模了

    对于 text1 的前 i 个字母与 text2 的前 j 个字母。

(leetcode-solve-problem 136) #+end_src

技巧

只出现一次的数字

(leetcode-solve-problem 136)

多数元素

投票、随机数

(leetcode-solve-problem 169)
#+begin_src emacs-lisp :tangle yes :comments link :results none
(leetcode-solve-problem 794)

把所有的方格的高度与位置加进一个最小堆。

从列表里面逐一弹出方格,查看其四周是否有矮于它的方格,如果有,把自己加进它的集合。

每一次合并都需要检测,是不是左上与右下都在这个点内,如果是的话,那么就返回现在的这个方格的高度,否则还需要继续查找。

颜色分类

(leetcode-solve-problem 169)

下一个排列

(leetcode-solve-problem 31)

寻找重复数

(leetcode-solve-problem 136)

并查集

水位上升的游泳池

(leetcode-solve-problem 794)

把所有的方格的高度与位置加进一个最小堆。

从列表里面逐一弹出方格,查看其四周是否有矮于它的方格,如果有,把自己加进它的集合。

每一次合并都需要检测,是不是左上与右下都在这个点内,如果是的话,那么就返回现在的这个方格的高度,否则还需要继续查找。