312. 戳气球
自上而下
戳气球会导致左右邻居的移动,因此将问题转化为添加气球
helper(i, j)
表示在i~j
这个开区间内添加气球,之所以开区间是因为左右区间设置为边界外,那里的气球是不能戳的,可以考虑到。
然后寻找这个区间添加后值最大的气球,对左右两边继续进行添加,对于每个区间,都会遍历每个值,然后对左右两边进行递归,从而求出
1 | class Solution { |
自下而上
1 | class Solution { |
戳气球会导致左右邻居的移动,因此将问题转化为添加气球
helper(i, j)
表示在i~j
这个开区间内添加气球,之所以开区间是因为左右区间设置为边界外,那里的气球是不能戳的,可以考虑到。
然后寻找这个区间添加后值最大的气球,对左右两边继续进行添加,对于每个区间,都会遍历每个值,然后对左右两边进行递归,从而求出
1 | class Solution { |
1 | class Solution { |
1 | class Solution { |
精简优化,思路同上
1 | class Solution { |
对于一串,每层把每个括号都删掉一次试试看,然后进入下一层,每层删掉的括号是一致的,当一层碰到有效后,把这一层所有有效的加入然后返回。
。。。。不想写(抄
迭代算法
1 | /** |
递归算法
太简单不写了
迭代算法
1 | /** |
递归
1 | /** |
冷冻期的处理:如果前一天卖出股票,这一天就不能卖,如果前一天没卖,这一天就能卖或者不卖。
对于目前的持股状态,根据卖出和不卖出,持有和不持有组合,共有四种情况:
对于1
由于我现在有并且当天没卖出,所以当天的值就是前一天1
情况或者前一天没股票但是买入了
,也就是3+今天买入后(冷冻期)
对于3
由于我现在没有而且当天也没有,说明我之前就没有,今天也不能买过来,所以我今天的收益就是3
和4
之中的最大值
对于4
由于我现在没有并且当天卖出了,则今天就不能买入了,所以前一天不能卖出,所以值就是前一天1的情况加上今天卖出的收益
。
以上三种状态同步进行,最后最大值会在3,4之间获得到
1 | class Solution { |
发现只用到了前一天的数据,所以可以把S(n)优化为O(1)
1 | class Solution { |
根据
1 | class Solution { |
优化空间后
1 | class Solution { |
1 | class Solution { |
review
1 | class Solution { |
直接看解析
1 | class Solution { |
1 | /** |
右->中->左
rightVal始终保存他右边树枝的最大值
我好傻
简单的思考方法:
中序单增,于是反中序为单减,对于每个节点加上他左边的和就行
迭代
1 | /** |
1 | class Solution { |
1 | class Solution { |
x-1会将x中最近的一个1变成0,而这个1左边的全变成1。
所以x&x-1
会使得这个最近的1及其右边全都变成0,而左边保持不变,则每次都如此操作,循环次数就是1的个数
对于矩阵
借助归并排序思想,把每一行视为一个递增序列,如果归并的话,就是把每一行归并序列合并为一个递增序列,但这题并不需要实现完整的操作
1 | 1 5 9 |
可以先窥探第一列,第一列是每一个行序列的最小值所组成的,因此第一列中的最小值毫无疑问是1,这里可以先弹出1,矩阵变为
1 | 5 9 |
若要继续判断,只需要判断5, 10, 12
中的最小值,然后继续弹出最小值
1 | 9 |
1 |
|
1 |
|
所以需要一个优先级队列来维护顶头最小,下面最大的一个堆,并且每个堆中的元素需要记录这个元素在矩阵中的坐标,从而可以在弹出后用它右边的元素接替。
代码如下:
1 | class Solution { |
less:当左边小于右边时,return true
priority_queue:当新进来的数导致了顺序错误,则return true。此处是新进来的数如果大于顶头的数,就return true。
因此类中应当重载<
操作符,当左边小于右边时return false,也就是左边大于右边时return true。
lhs < rhs
时,调用的是lhs的重载操作符,所以需要lhs>rhs返回true,所以是this->val>ele.val。
1 | class Solution { |
当lo和hi相遇时,他们肯定收敛一个矩阵中具有的数值
若right不在矩阵中
如果right在矩阵中
与上述类似
所以,根据上述情况,解可以始终保证位于区间lo~hi之中,当lo和hi相等之时,就可以保证他们必定为解。