1. 程式人生 > 其它 >leetcode 劍指 Offer 54. 二叉搜尋樹的第k大節點

leetcode 劍指 Offer 54. 二叉搜尋樹的第k大節點

技術標籤:演算法資料結構leetcode面試java

劍指 Offer 54. 二叉搜尋樹的第k大節點

給定一棵二叉搜尋樹,請找出其中第k大的節點。

示例 1:

示例 2:

限制:

1 ≤ k ≤ 二叉搜尋樹元素個數

解法一:

按右根左的順序遞迴遍歷二叉搜尋樹,第k個結點,即使第k大的結點

 1 class Solution {
 2     public int kth = 0;
 3     public int k = 0;
 4     // 遞迴中序遍歷,右根左,第k個結點,即使第k大的結點
 5     public int kthLargest(TreeNode root, int k) {
 6         this.k = k;
 7         midTravesal(root);
 8         return kth;
 9     }
10 
11     public void midTravesal(TreeNode root){
12 
13         if(root != null){
14             midTravesal(root.right);
15             k--;
16             if(k == 0){
17                 kth = root.val;
18                 return;
19             }   
20             midTravesal(root.left);
21         }
22     }
23 }

leetcode執行時間為0ms, 空間為38.8mb

複雜度分析:

時間複雜度:遍歷了樹的k個結點,所以時間複雜度為O(k)

空間複雜度:遞迴棧的深度就是空間複雜度,二叉搜尋樹的最大深度為O(n), 最小深度為O(logn)

解法二:

利用棧的方式實現非遞迴訪問棧,同樣訪問的第k個結點是我們的目標結點

 1 class Solution {
 2 
 3     // 利用棧實現中序遍歷,右根左,第k個結點,即使第k大的結點
 4     public int kthLargest(TreeNode root, int k) {
 5         Stack<TreeNode> stack = new Stack<TreeNode>();
 6         TreeNode top = root;
 7         while(!stack.isEmpty() || top != null){
 8             while(top != null){
 9                 stack.push(top);
10                 top = top.right;
11             }
12             top = stack.pop();
13             k--;
14             if(k == 0){
15                 return top.val;
16             }
17             top = top.left;
18         }
19         return 0;
20     }
21 }

leetcode執行時間為1ms, 空間為38.5mb

複雜度分析:

時間複雜度:遍歷了樹的k個結點,所以時間複雜度為O(k)

空間複雜度:棧的大小就是空間複雜度,所以同樣是O(k)