方法1:双函数法(新建的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)
//指导思想:【树递归,能拆就拆】
//拆开的三大好处:接口清晰、时空高效、简化逻辑(不易写错)==>对人对机器都好方法2:单函数(原函数上直接递归)
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)
京公网安备 11010502036488号