zoukankan      html  css  js  c++  java
  • 230. Kth Smallest Element in a BST

    题目:

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

    Note: 
    You may assume k is always valid, 1 ≤ k ≤ BST's total elements.

    Follow up:
    What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

    Hint:

      1. Try to utilize the property of a BST.
      2. What if you could modify the BST node's structure?
      3. The optimal runtime complexity is O(height of BST).

    链接:  http://leetcode.com/problems/kth-smallest-element-in-a-bst/

    题解:

    用了比较笨的方法 - inorder traversal,做了一下剪枝。

    Time Complexity - O(k), Space Complexity - O(k)。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        List<Integer> nodeVal = new ArrayList<Integer>();
        
        public int kthSmallest(TreeNode root, int k) {
            if(root == null)
                return 0;
            inorder(root, k);
            return nodeVal.get(k - 1);
        }
        
        private void inorder(TreeNode root, int k) {
            if(nodeVal.size() >= k)
                return;
            if(root == null)
                return;
            inorder(root.left, k);
            nodeVal.add(root.val);
            inorder(root.right, k);
            
        }
    }

    Update:

    Time Complexity - O(n), Space Complexity - O(1)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        
        private int count = 0;
        private int res = 0;
        public int kthSmallest(TreeNode root, int k) {
            if(root == null)
                return 0;
            inorder(root, k);
            return res;
        }
        
        private void inorder(TreeNode root, int k) {
            if(root == null)
                return;
            if(count >= k)
                return;
            inorder(root.left, k); 
            if(count >= k)
                return;
            res = root.val;
            count++;
            inorder(root.right, k);
            
        }
    }

    二刷:

    一开始想到是用inorder traversal,可以建立一个list, 当list.size() == k的时候我们跳出,最后返回list.get(k - 1)。 后来想到我们可以继续优化,并不需要使用list来保存结果。

    Java:

    Inorder traversal:

    Time Complexity - O(k), Space Complexity - O(k)。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public int kthSmallest(TreeNode root, int k) {
            List<Integer> res = new ArrayList<>();
            inOrder(res, root, k);
            return res.size() >= k ? res.get(k - 1) : 0;
        }
        
        private void inOrder(List<Integer> res, TreeNode root, int k) {
            if (root == null || res.size() >= k)  return;
            inOrder(res, root.left, k);
            res.add(root.val);
            inOrder(res, root.right, k);
        }
    }

    优化:

    不用建立List,直接使用count来记录

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        private int count = 0;
        private int res = 0;
        
        public int kthSmallest(TreeNode root, int k) {
            inOrder(root, k);
            return res;
        }
        
        private void inOrder(TreeNode root, int k) {
            if (root == null || count >= k)  return;
            inOrder(root.left, k);
            count++;
            if (count == k) res = root.val;
            inOrder(root.right, k);
        }
    }

    三刷:

    依然是in-order traversal,写了iterative的版本。 Follow up在查询多和更改多的情况下,我们可以为BST的每个节点增加一个int count,然后进行二分查找。

    Java:

    Time Complexity - O(k), Space Complexity - O(k)。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public int kthSmallest(TreeNode root, int k) {
            if (root == null) return Integer.MAX_VALUE;
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = root;
            stack.push(node);
            while (node != null || !stack.isEmpty()) {
                if (node != null) {
                    stack.push(node);
                    node = node.left;
                } else {
                    node = stack.pop();
                    k--;
                    if (k == 0) return node.val;
                    node = node.right;
                }
            }
            return root.val;
        }
    }

    Reference:

    https://leetcode.com/discuss/68052/two-easiest-in-order-traverse-java

    https://leetcode.com/discuss/43267/4-lines-in-c

    https://leetcode.com/discuss/43464/what-if-you-could-modify-the-bst-nodes-structure

    https://leetcode.com/discuss/43299/o-k-space-o-n-time-10-short-lines-3-solutions

    https://leetcode.com/discuss/45684/share-my-c-iterative-alg

    https://leetcode.com/discuss/43771/implemented-java-binary-search-order-iterative-recursive

  • 相关阅读:
    实现 js 数据类型的判断函数type
    函数防抖 debounce
    验证对象属性是否存在
    解析字串
    完成将 toChineseNum, 可以将数字转换成中文大写的表示,处理到万级别,例如 toChineseNum(12345),返回 一万二千三百四十五
    前端开发仓库
    javascript功能插件大集合,写前端的亲们记得收藏
    Memcached存储命令
    Memcached存储命令
    Memcached 简介、安装和基本使用
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4999289.html
Copyright © 2011-2022 走看看