heap O(logn)
1 | class MedianFinder { |
1 | class MedianFinder { |
heap O(logn)
1 | class MedianFinder { |
1 | class MedianFinder { |
O(h) time O(1) space
跟160. Intersection of Two Linked Lists一样
1 | /* |
multiset/hashheap O(nlogk)
跟239. Sliding Window Maximum方法不一样,太smart了
讨论一下添加删除的四种情况即可,两个if都能cover
1 | class Solution { |
1 | class Solution { |
直接覆盖 O(n)
1 | class Solution { |
swap O(n)
1 | class Solution { |
O(n) time O(1) space
这道题的思路跟普通的reverse不一样!!
curr是固定的,永远指向初始的第m个结点,anchor也是固定的,永远是curr的前继结点
每次curr都是和它的succ交换,然后让next的下一个指向anchor的下一个结点,最后anchor的下一个指向那个succ结点
1 | /** |
greedy O(n2) time
先排序,第一位降序,第二位升序,然后按照第二位插入排序
第一位小说明矮,靠后排,第二位大说明比他高的人多,靠后排
每次把一个人往前放,不会影响比他高的人的位置,不管是在他之前还是之后,之后影响比他矮且比他更靠后的人的位置,但是我们后面会处理他们,所以不用管他们
People are only counting (in their k-value) taller or equal-height others standing in front of them. So a smallest person is completely irrelevant for all taller ones. And of all smallest people, the one standing most in the back is even completely irrelevant for everybody else. Nobody is counting that person. So we can first arrange everybody else, ignoring that one person. And then just insert that person appropriately. Now note that while this person is irrelevant for everybody else, everybody else is relevant for this person - this person counts exactly everybody in front of them. So their count-value tells you exactly the index they must be standing.
So you can first solve the sub-problem with all but that one person and then just insert that person appropriately. And you can solve that sub-problem the same way, first solving the sub-sub-problem with all but the last-smallest person of the subproblem. And so on. The base case is when you have the sub-…-sub-problem of zero people. You’re then inserting the people in the reverse order, i.e., that overall last-smallest person in the very end and thus the first-tallest person in the very beginning. That’s what the above solution does, Sorting the people from the first-tallest to the last-smallest, and inserting them one by one as appropriate.
1 | class Solution { |
问一下target有没有长度限制!!
用这个 dp + memo O(N + N2 + … + NT) = O((N * (NT - 1) / (N - 1))即每一层有N次循环 一共T层 N是sticker个数 T是target长度
cache[target]是所求结果,cache[“”] = 0
对每个sticker统计字母频
对每一层的target统计字母频
用每一个sticker去尝试拼凑部分target,拼不上的部分组成新的target再递归
遍历所有的可能,不断更新最小值即可
1 | class Solution { |
状态压缩dp O(2n*(S+n*s)) n是target长度 S是stickers所有字母个数 s是stickers的个数
target从一个字母都找不到匹配到所有字母都匹配上一共2n个状态
1 | class Solution { |
状态压缩dp O(2n*n*S) n是target长度 S是stickers所有字母个数
target从一个字母都找不到匹配到所有字母都匹配上一共2n个状态
1 | class Solution { |
这道题的前提是不能有相同海拔且海拔高度必须从0到n2-1
类dijkstra O(n2logn) time O(n2) space
这道题的难点是能看出来这其实是一个求最大边费用最小的最短路径(dijkstra)的题(和传统的求最小费用和的最短路径不一样),从一个点到邻居点的费用就是邻居点的海拔高度,这道题需要用dijkstra找到一条路径,使得路径上所有点的最高海拔高度尽可能小(这样就能用最少的时间从起点到终点),因为要维护尽可能小的海拔高度,所以要用堆,每次用堆顶的点的海拔高度来更新全局海拔高度,并将该点的邻接点入堆,至于选择四个方向的哪个邻居,完全基于贪心(dijkstra的本质),反正四个方向的邻居我们都会缓存起来,这样每次更新后实际上都会得到一个更大范围的包含最短路径的区域,在这道题里,这个区域的大小等于这个区域的海拔落差(最高海拔),并且该最短路径一定要经过这个最高海拔的点,因为(反证法)如果能找到另一条路径且最高海拔的点j比结果的最高海拔i要低,那么点j一定在点i之前入堆,且点i不可能入堆
跟1102. Path With Maximum Minimum Value 思路完全一样
1 | class Solution { |
采用队列进行局部优化后
1 | class Solution { |
二分+dfs O(n2logn) time
因为所有的海拔高度是从0到n2-1分布且最后答案一定在grid里面,所以适用二分查找,对于每一个candidate值,dfs遍历整个grid看是否能在candidate值以内(不超过)找到一条从grid[0][0]到grid[n - 1][n - 1]的路径
1 | class Solution { |
最小边费用最大的最短路径O(RClogRC) time O(RC) space
跟778. Swim in Rising Water思路完全一样
类dijkstra
用最大堆 只找大数 然后沿着大数走 同时用大数来更新结果 直到达到目的地
1 | class Solution { |
1 | class Solution { |
union-find
1 | class Solution { |
O(1) time O(n) space
1 | class TicTacToe { |