方法一:双函数
//新建的void函数 用于修改全局变量res;主函数负责return public class Solution { private int count = 0;//全局(类)变量可以不初始化,int默认为0 //等价于private int count; private TreeNode res = null;//等价于private TreeNode res; //全局(类)变量不能这样初始化:private TreeNode result=new TreeNode();这种方法用于函数内局部变量初始化 TreeNode KthNode(TreeNode pRoot, int k){ count = k; Find(pRoot); return res; } void Find(TreeNode pRoot){ if(pRoot!=null && res==null){//res==null用于剪枝加速;本题不剪枝也答案正确 //也可以用count>=0来剪枝 Find(pRoot.left); if(--count == 0)res=pRoot;//找到,立即结束 Find(pRoot.right); } } }//时间O(N) 空间O(logN) //指导思想:【树递归,能拆就拆】 //拆开的三大好处:接口清晰、时空高效、简化逻辑(不易写错)==>对人对机器都好
方法二:单函数(原函数上直接递归)
public class Solution { int count = 0; TreeNode KthNode(TreeNode pRoot, int k) {//单函数:代码短,但逻辑复杂 if(pRoot != null){//dfs的剪枝尽量不要分左右子树来写,这样集中写比较好 TreeNode left = KthNode(pRoot.left,k); if(left != null)return left;//帮助返回res,并拦截内层的null if(++count == k)return pRoot;//【一旦找到,就会剪枝、logn时间迅速向上】//找不到就一直没有return TreeNode right = KthNode(pRoot.right,k); if(right != null)return right;//帮助返回res,并拦截内层的null } return null;//最外层的null才可能返回,其他都会被拦截 } }//时间O(N) 空间O(logN)