算法:哈希、双指针

some tips

双指针的用法相对灵活的。

  • 可以归纳为以下几种:
    • →→
    • → ←
    • ←←
    • ←→
  • 另一种情况是两个数组,一个数组一个指针
  • 都需要注意是否需要排序的问题

哈希表:空间换时间

注意哪些可以作为key,哪些不可以

题目

18. 四数之和 \ 454. 四数相加 II

这种二数和、三数和、四数和都可以用双指针、哈希表。但复杂度会一直增加。需要做一些优化。

169. 多数元素 \ 229. 求众数 II

可以用投票法,就是看做候选人,不一样的就扣。

658. 找到 K 个最接近的元素

这就是←→双指针的用法,先用二分法找到,然后开始左右移动。

75. 颜色分类

也是用两个指针来定位元素的位置,还要有一个指针来确定当前检查的颜色。

11. 盛最多水的容器

→ ←双指针的用法,需要判断移动的条件,即短的动(容量有限)

42. 接雨水【困难、重要】

双指针:

  • 可以根据行来计算。
  • 两个指针,逐个检查。比较的对象是当前左边最大,和当前右边最大。小了就会积水。

动态规划:
分享一个不错题解作者的理解:
maxleft[i] 表示第 i 个柱子左边最高柱子的高度,同理 maxright 也一样。这个其实和方法三的思路是一样的,只是方法三不用动态数组了,而是使用一个变量,这样可以减少空间的使用。所谓动态规划就是出现一些重叠子问题时,我们事先记住它。比如我问 1+1+1+1+1 等于几时,你会回答是 5,如果我说再➕1呢,你肯定会脱口而出是6。之所以脱口而出是因为i你在计算时记住了前面的结果是5,而不是重新计算一遍。

本题也一样,我们对于每次柱子 i,都要重新遍历它的左边和右边来分别寻找两边最高的柱子,这样对于每个 i 我们会重复比较,导致时间复杂度变大。因此我们的解决办法是利用一个 maxleft 和 maxright,maxleft【i】就表示 i 左边最高的柱子高度是 maxleft【i】。。。

当maxleft和maxright填满以后,我们重新遍历一遍,这时对于每一个 i 都可以通过直接查询这两个数组获得两边最高的高度,而不必浪费时间反复寻找。

219. 存在重复元素 II

就是创建一个字典,记录key是元素,value是索引。然后判断索引差

220. 存在重复元素 III

  • 暴力法:
    维护一个长度为k的窗口,逐一比较。
    存在冗余运算,无法通过
  • 桶排序的思想
    将数组中的值经过映射变成key放入桶中。
    保证只需要在当前桶和相邻桶进行比较是否小于等于t。
    对于索引,只需要定期清理桶中过期的值即可。
    对于dict。可以用key是否in来判断,key in dict, dict.pop(key)
  • 二叉搜索树(to do)

560. 和为K的子数组

暴力法很容易想到,但超时间。
想过用双指针(滑动窗口),但是这种没序,又要求连续,不好处理指针移动,试了下很麻烦,没做出来。

学了一个新的,前缀和。
也就是 s u m ( n u m s [ i : j ] ) = s u m ( n u m s [ : j ] ) ) − s u m ( n u m s [ : i ] ) sum(nums[i:j]) =sum(nums[:j]))-sum(nums[:i]) sum(nums[i:j])=sum(nums[:j]))sum(nums[:i])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值