LeetCode刷题时遇到的有“名”算法(频繁更新中。。。)

1. 分治法(240.搜索二维矩阵 II)

思路:

  • 左下角的元素是这一行中最小的元素,同时又是这一列中最大的元素。比较左下角元素和目标:
    • 若左下角元素等于目标,则找到
    • 若左下角元素大于目标,则目标不可能存在于当前矩阵的最后一行,问题规模可以减小为在去掉最后一行的子矩阵中寻找目标
    • 若左下角元素小于目标,则目标不可能存在于当前矩阵的第一列,问题规模可以减小为在去掉第一列的子矩阵中寻找目标
  • 若最后矩阵减小为空,则说明不存在

应用扩展

  • 归并排序 

2.动态规划(887. Super Egg Drop )

联系

  • 没有分叉,一路推理 ➜ 〔线性结构〕
  • 看到决策结果有分叉 ➜ 〔树形结构〕
  • 若在推理过程中,产生交汇 ➜ 〔图结构〕

3.递归回溯(131. 分割回文串)

 特点:

  • 递归:在函数的定义中使用函数自身的方法,把规模大的问题转化为规模小的子问题来解决。
  • 回溯:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。

应用

  • 递归:汉诺塔
  • 回溯:四/八皇后

4. 前缀树

特点:

即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

思想:

空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。 
它有3个基本性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。

5.大顶堆(378. 有序矩阵中第K小的元素

思路:

设定K容量堆,依次存入大值,多于K个后删除堆内最大值,排序完成后堆首值即为矩阵内第K小值。 

注:对于python语言执行速度较差,用大顶堆的思路解决第K小元素问题时运行超时,需安装如下思路解题:

class Solution:
    def kthSmallest(self, matrix, k):
        """
        :type matrix: List[List[int]]
        :type k: int
        :rtype: int
        """
        lo, hi = matrix[0][0], matrix[-1][-1]
        while lo <= hi:
            mid = lo + (hi-lo)//2
            loc = self.countLower(matrix, mid)
            if loc >= k:
                hi = mid - 1
            else:
                lo = mid + 1
        return lo

    def countLower(self, matrix, num):
        i, j = len(matrix) - 1, 0
        cnt = 0
        while i >= 0 and j < len(matrix[0]):
            if matrix[i][j] <= num:
                cnt += i + 1
                j += 1
            else:
                i -= 1
        return cnt

6.快慢指针(141.环形链表)

给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

思路:

通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至 O(1)O(1)。慢指针每次移动一步,而快指针每次移动两步。

如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false

现在考虑一个环形链表,把慢指针和快指针想象成两个在环形赛道上跑步的运动员(分别称之为慢跑者与快跑者)。而快跑者最终一定会追上慢跑者。这是为什么呢?考虑下面这种情况(记作情况 A) - 假如快跑者只落后慢跑者一步,在下一次迭代中,它们就会分别跑了一步或两步并相遇。

其他情况又会怎样呢?例如,我们没有考虑快跑者在慢跑者之后两步或三步的情况。但其实不难想到,因为在下一次或者下下次迭代后,又会变成上面提到的情况 A。

复杂度分析

  • 时间复杂度:O(n)O(n), 让我们将 nn 设为链表中结点的总数。为了分析时间复杂度,我们分别考虑下面两种情况。

    • 链表中不存在环:
      快指针将会首先到达尾部,其时间取决于列表的长度,也就是 O(n)O(n)。

    • 链表中存在环:
      我们将慢指针的移动过程划分为两个阶段:非环部分与环形部分:

      1. 慢指针在走完非环部分阶段后将进入环形部分:此时,快指针已经进入环中 \text{迭代次数} = \text{非环部分长度} = N迭代次数=非环部分长度=N

      2. 两个指针都在环形区域中:考虑两个在环形赛道上的运动员 - 快跑者每次移动两步而慢跑者每次只移动一步。其速度的差值为1,因此需要经过 \dfrac{\text{二者之间距离}}{\text{速度差值}}速度差值二者之间距离​ 次循环后,快跑者可以追上慢跑者。这个距离几乎就是 "\text{环形部分长度 K}环形部分长度 K" 且速度差值为 1,我们得出这样的结论 \text{迭代次数} = \text{近似于}迭代次数=近似于 "\text{环形部分长度 K}环形部分长度 K".

    因此,在最糟糕的情形下,时间复杂度为 O(N+K)O(N+K),也就是 O(n)O(n)。

  • 空间复杂度:O(1)O(1), 我们只使用了慢指针和快指针两个结点,所以空间复杂度为 O(1)O(1)。

 7.归并排序(手懒中。。)

(python,使用list实现链表https://blog.csdn.net/dinnerhowe/article/details/58191823

8.快速排序(手懒中。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值