算法dfs——二叉搜索树中最接近的值 II

901. 二叉搜索树中最接近的值 II

中文
English

给定一棵非空二叉搜索树以及一个target值,找到 BST 中最接近给定值的 k 个数。

样例

样例 1:

输入:
{1}
0.000000
1
输出:
[1]
解释:
二叉树 {1},表示如下的树结构:
 1

样例 2:

输入:
{3,1,4,#,2}
0.275000
2
输出:
[1,2]
解释:
二叉树 {3,1,4,#,2},表示如下的树结构:
  3
 /  \
1    4
 \
  2

挑战

假设是一棵平衡二叉搜索树,你可以用时间复杂度低于O(n)的算法解决问题吗( n 为节点个数)?

注意事项

  • 给出的target值为浮点数
  • 你可以假设 k 总是合理的,即 k ≤ 总节点数
  • 我们可以保证给出的 BST 中只有唯一一个最接近给定值的 k 个值的集合
"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""

class Solution:
    """
    @param root: the given BST
    @param target: the given target
    @param k: the given k
    @return: k values in the BST that are closest to the target
    """
    def closestKValues(self, root, target, k):
        if root is None or k == 0:
            return []
            
        nums = self.get_inorder(root)
        left = self.find_lower_index(nums, target)
        right = left + 1
        results = []
        for _ in range(k):
            if (right >= len(nums)) or (left >=0 and target - nums[left] < nums[right] - target):
                results.append(nums[left])
                left -= 1
            else:
                results.append(nums[right])
                right += 1
        return results
        
    def get_inorder(self, root):
        result = []
        stack = []
        node = root
        while stack or node:
            if node:
                stack.append(node)
                node = node.left
            else:
                node = stack.pop()
                result.append(node.val)
                node = node.right
        return result
        
        
    def find_lower_index(self, nums, target):
        """
        find the largest number < target, return the index
        """
        start, end = 0, len(nums) - 1
        while start + 1 < end:
            mid = (start + end) // 2
            if nums[mid] < target:
                start = mid
            else:
                end = mid
                
        if nums[end] < target:
            return end
        
        if nums[start] < target:
            return start
            
        return -1

 更优的解法,todo

 

相关的题目:

11. 二叉查找树中搜索区间

中文
English

给定一个二叉查找树和范围[k1, k2]。按照升序返回给定范围内的节点值。

样例

样例 1:

输入:{5},6,10
输出:[]
        5
它将被序列化为 {5}
没有数字介于6和10之间

样例 2:

输入:{20,8,22,4,12},10,22
输出:[12,20,22]
解释:
        20
       /  \
      8   22
     / \
    4   12
它将被序列化为 {20,8,22,4,12}
[12,20,22]介于10和22之间


"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""

class Solution:
    """
    @param root: param root: The root of the binary search tree
    @param k1: An integer
    @param k2: An integer
    @return: return: Return all keys that k1<=key<=k2 in ascending order
    """
    def searchRange(self, root, k1, k2):
        # write your code here
        """
        # recursive solution
        if not root:
            return []
        if root.val < k1:
            return self.searchRange(root.right, k1, k2)
        elif root.val > k2:
            return self.searchRange(root.left, k1, k2)
        else:
            return self.searchRange(root.left, k1, k2) + [root.val] + \
                self.searchRange(root.right, k1, k2)
        """
        
        result = []
        q = [root]
        
        while q:
            node = q.pop()
            if not node: 
                continue
            
            if k1 <= node.val <= k2:
                result.append(node.val)
                q.append(node.left)
                q.append(node.right)
            elif node.val < k1:
                q.append(node.right)
            else:
                q.append(node.left)
        
        result.sort()                
        return result
        

 

85. 在二叉查找树中插入节点

中文
English

给定一棵二叉查找树和一个新的树节点,将节点插入到树中。

你需要保证该树仍然是一棵二叉查找树。

样例

样例  1:
	输入: tree = {}, node= 1
	输出: {1}
	
	样例解释:
	在空树中插入一个点,应该插入为根节点。

	
样例 2:
	输入: tree = {2,1,4,3}, node = 6
	输出: {2,1,4,3,6}
	
	样例解释: 
	如下:
	
	  2             2
	 / \           / \
	1   4   -->   1   4
	   /             / \ 
	  3             3   6
	

挑战

能否不使用递归?

注意事项

保证不会出现重复的值

 

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""


class Solution:
    """
    @param: root: The root of the binary search tree.
    @param: node: insert this node into the binary search tree
    @return: The root of the new binary search tree.
    """
    def insertNode(self, root, target):
        # write your code here
        if not root:
            return target
            
        node = root
        while node:
            if target.val > node.val:
                if node.right is None:
                    node.right = target
                    return root
                node = node.right
            elif target.val < node.val:
                if node.left is None:
                    node.left = target
                    return root
                node = node.left
        return root
        

 另外递归的解法也很优雅:

"""
在树上定位要插入节点的位置。

如果它大于当前根节点,则应该在右子树中,
如果它小于当前根节点,则应该在左子树中。
(二叉查找树中保证不插入已经存在的值)
"""
class Solution:
    """
    @param: root: The root of the binary search tree.
    @param: node: insert this node into the binary search tree
    @return: The root of the new binary search tree.
    """
    def insertNode(self, root, node):
        # write your code here
        return self.__helper(root, node)
    
     # helper函数定义成私有属性   
    def __helper(self, root, node):     
        if root is None:
            return node
        if node.val < root.val:
            root.left = self.__helper(root.left, node)
        else:
            root.right = self.__helper(root.right, node)
        return root

 

posted @ 2019-10-07 22:09  bonelee  阅读(1091)  评论(0编辑  收藏  举报