这道题做过了不少次了,一直没有找到归类的类型。然后今天看的时候有了灵感,找到了对应的其他类型:
1,先说high-level上这题的特意:一般来说,都会返回树的root,或者list 的head,但这道题不用,只是一个void的类型。helper function返回的不是头,而是尾巴!!这是特意的的地方,这个tail是为了下一次 连接 hook up用的!精准。所以helper function的作用是:输入一个根节点,返回的时候flatten之后的 尾节点!
2,代码结构的相似之处,类似于 check balance tree 那道题,把 root,root.left,root.right 用三个变量分别记录,而且这道题的中用变量来记录是必须的!因为要把root的左右子树都断开。
3,一点拓展的想法:这道题是 一直往右边 flatten,其实往左边flatten也是一样的。变化一下顺序。
4,如果这个题需要返回root,应对的方式是 在主方法里,加一个 dummyRoot,其left指向 root,然后其他代码和 helper function都不变。
代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public void flatten(TreeNode root) {
if(root==null) return;
TreeNode tail= flattenAndReturnTail(root);
return;
}
public TreeNode flattenAndReturnTail(TreeNode root){ // the name of interface is important, for both the interview and readability
// use three points to get the root, leftchild and rightchild, same thing for checking the leftchild and the rightchild.
// ALSO, importantly, disconnect all the link, for the easy re-attached later.
TreeNode tail=root;
TreeNode left=root.left;
TreeNode right=root.right;
root.left=null;
root.right=null;
if(left==null && right==null) return tail;
// actually, the flatten means, always go to the right side. So when asking doing it in the reversed way, you should also know it.
if(left!=null){ // since it is for the interface that the argu should be non-null pointer
tail.right=left;
tail=flattenAndReturnTail(left);
}
if(right!=null){
tail.right=right;
tail=flattenAndReturnTail(right);
}
return tail;
}
}
// 这里可以总结的地方是:把leftchild and rightchild 拆下来进行分别的判断,其实主要原因还是要用到 leftchild 和 rightchild
// 貌似做到这里,tree的题目已经做了10+了,可以总结一下思路了,从最原始的 3种遍历说起
// 常用方法1: recursive的方法,两道例题:打印和convert to list,推而广之,只要是基于对所有node都进行遍历的题都适合用recursion
// 常用方法2: iterative的方法,同样两道例题,但是 如果是部分遍历,要求在中间某个时候打断,就比较难用recursion,这时用iterative会简单得多,这个时候有个核心的对BST进行排序的引擎代码模版,特点是只有pop()出来的才是排序好的,而push()的时候并不是,所以只要在pop的同时,进行 计数或者其他任何动作opts,就可以把基本所有问题解决了。比如topK(convert to list), k-th smallest, k-th largest, valid BST(关于pre的初始值,和变化值还不是非常熟悉) 等等。
// 嗯嗯,现在刷提感觉确实好很多了,就是要进入到总结归纳的level。就以上面两种套路作为第一个划分,然后在这基础上进行 原型总结和题目扩充。