解析
max ksubarray sum: 最大和 of 连续子序列 => 最大和 of k份连续子序列 属于dp,30行代码搞定,注意一些边界。
substr diff: 无queue的区间滑动窗口,记录当前最大值
maxtree:
九章算法中有讲到, 对每个节点,找到离他最近且比它大的左右两个节点中较小的那个,作为他的父节点。
其中,找父节点: 用递增栈分别从左向右和从右向左扫描一次,对每个节点取栈顶元素即可。 在O(n)时间里就可以找到距离该节点最近的比他大的节点。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param A: Given an integer array with no duplicates.
* @return: The root of max tree.
*/
TreeNode* maxTree(vector<int> A) {
// write your code here
int n = A.size();
// allocate tree
TreeNode * nodes = new TreeNode[n];
for(int i =0; i<n; i++){
nodes[i] = TreeNode(A[i]);
}
// obtain the left/right nearest larger node
stack<int> ss;
vector<int> lp(n, -1), rp(n, -1);
for(int i =0; i<n; i++){
while(!ss.empty() && A[i]>A[ss.top()]){
ss.pop();
}
if(!ss.empty()){
lp[i] = ss.top();
}
ss.push(i);
}
ss=stack<int>();
for(int i =n-1; i>=0; i--){
while(!ss.empty() && A[i]>A[ss.top()]){
ss.pop();
}
if(!ss.empty()){
rp[i] = ss.top();
}
ss.push(i);
}
// construct tree
TreeNode * root = NULL;
for(int i = 0; i<n; i++){
if(lp[i]>=0 && (rp[i]<0 || A[rp[i]]>A[lp[i]])){
nodes[lp[i]].right = &nodes[i];
}
else if(rp[i]>=0 && (lp[i]<0 || A[lp[i]]>A[rp[i]])){
nodes[rp[i]].left = &nodes[i];
}else{
root = &nodes[i];
}
}
return root;
}
};
tree iterator:
实质:找一个节点的中序下一个节点。
用dfs(root, p) 在root树中,找p的下一个节点。 代价是O(logn)
如果要O(1)的时间代价,需要一个栈(空间O(logn))保存当前的路径(root ->xx -> p)。
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right =