剑指 Offer 54. 二叉搜索树的第k大节点
思路:
一开始完全思路就搞错了,想了一个类似与递归的思路,先找到最大的,然后一步一步找次大的,
又因为如何找父亲节点的事想了一阵
结果突然发现,可以直接输出成一个数组啊,然后直接取数组就行了
class Solution { List<Integer> list=new ArrayList<>(); public int kthLargest(TreeNode root, int k) { if(root==null) {return 0;} //中序遍历输出一个数组 tree2List(root); return list.get(list.size()-k); } public void tree2List(TreeNode root) { if(root==null) {return;} if(root.left!=null) {tree2List(root.left);} list.add(root.val); if(root.right!=null) {tree2List(root.right);} } }
这里需要注意,这个列表需要弄成全局变量(类的变量)
另外dfs时不需要判断子树为null,直接
void dfs(TreeNode root) { if(root == null) return; dfs(root.right); // 右 System.out.println(root.val); // 根 dfs(root.left); // 左 }
问题当然很明显,无论k为多少,都直接把整个树都中序遍历了
忘记了中序遍历可以交换顺序(右子树,节点,左子树)
然后再加入一个计数器,这样能在计到k的时候直接返回
int count=0, res=0;//形参k不能随着dfs的迭代而不断变化,为了记录迭代进程和结果,引入类变量count和res。 public int kthLargest(TreeNode root, int k) { this.count=k;//利用形参值k对类变量count进行初始化 dfs(root);//这里不要引入形参k,dfs中直接使用的是初始值为k的类变量count return res; } public void dfs(TreeNode root){ if(root==null||count==0) return;//当root为空或者已经找到了res时,直接返回 dfs(root.right); if(--count==0){//先--,再判断 res = root.val; return;//这里的return可以避免之后的无效迭代dfs(root.left); } dfs(root.left); }
理解:
处理节点的顺序是严格按照从大到小的
然后每次处理count--了
因此当count等于0了,就直接该返回了
要多想想递归
要多想想dfs
要多想想二叉搜索树