[LeetCode] Closest Binary Search Tree Value II
2015-08-30 18:50
573 查看
Problem Description:
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Note:
Given target value is a floating point.
You may assume k is always valid, that is: k ≤ total nodes.
You are guaranteed to have only one unique set of k values in the BST that are closest to the target.
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
Hint:
Consider implement these two helper functions:
Try to assume that each node has a parent pointer, it makes the problem much easier.
Without parent pointer we just need to keep track of the path from the root to the current node using a stack.
You would need two stacks to track the path in finding predecessor and successor node separately.
There is a very simple idea to keep a max heap of size k and elements in the heap are sorted by their absolute difference from target. For the max heap, we will simply use the default priority_queue. Then we simply traverse the tree and push all its nodes to the heap while maintaining the size of heap not larger than k.
The code is as follows.
Well, the hints of the problem suggest a solution using two stacks to track the predecessors and successors. This post has shared a nice implementation of it. The code is rewritten in C++ as follows.
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Note:
Given target value is a floating point.
You may assume k is always valid, that is: k ≤ total nodes.
You are guaranteed to have only one unique set of k values in the BST that are closest to the target.
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
Hint:
Consider implement these two helper functions:
getPredecessor(N), which returns the next smaller node to N.
getSuccessor(N), which returns the next larger node to N.
Try to assume that each node has a parent pointer, it makes the problem much easier.
Without parent pointer we just need to keep track of the path from the root to the current node using a stack.
You would need two stacks to track the path in finding predecessor and successor node separately.
There is a very simple idea to keep a max heap of size k and elements in the heap are sorted by their absolute difference from target. For the max heap, we will simply use the default priority_queue. Then we simply traverse the tree and push all its nodes to the heap while maintaining the size of heap not larger than k.
The code is as follows.
class Solution { public: vector<int> closestKValues(TreeNode* root, double target, int k) { priority_queue<pair<double, int>> pq; closestK(root, pq, target, k); vector<int> closest; while (!pq.empty()) closest.push_back(pq.top().second), pq.pop(); return closest; } private: void closestK(TreeNode* node, priority_queue<pair<double, int>>& pq, double target, int k) { if (!node) return; pq.push(make_pair(abs(target - node -> val), node -> val)); if (pq.size() > k) pq.pop(); closestK(node -> left, pq, target, k); closestK(node -> right, pq, target, k); } };
Well, the hints of the problem suggest a solution using two stacks to track the predecessors and successors. This post has shared a nice implementation of it. The code is rewritten in C++ as follows.
class Solution { public: vector<int> closestKValues(TreeNode* root, double target, int k) { vector<int> closest(k); stack<int> pre, suc; inorder(root, target, false, pre); inorder(root, target, true, suc); for (int i = 0; i < k; i++) { if (pre.empty()) closest[i] = suc.top(), suc.pop(); else if (suc.empty()) closest[i] = pre.top(), pre.pop(); else if (abs(target - pre.top()) < abs(target - suc.top())) closest[i] = pre.top(), pre.pop(); else closest[i] = suc.top(), suc.pop(); } return closest; } private: void inorder(TreeNode* root, double target, bool reversed, stack<int>& s) { if (!root) return; inorder(reversed ? root -> right : root -> left, target, reversed, s); if ((reversed && root -> val <= target) || (!reversed && root -> val > target)) return; s.push(root -> val); inorder(reversed ? root -> left : root -> right, target, reversed, s); } };
相关文章推荐
- iOS阶段学习第33天笔记(自定义标签栏(UITabBar)介绍)
- Memo 安装 Mirantis Fuel - OpenStack安装和管理软件
- C#基础------可空类型 StringBuilder
- queue
- IOS基础UI之(一)简单的qq登录
- UITableViewCell 自适应高度
- IOS 开发 点击屏幕非UITextField处 也收回键盘
- 微软笔试题 HihoCoder#1137: Recruitment 题解
- iOS学习笔记03—Key-Value-Coding(KVC,键/值编码)
- UISegmentedControl
- StringBuilder与StringBuffer的区别(转)
- iOS用UIScorllView实现两指缩放功能
- JMeter非GUI方式运行时动态设置线程组及传参
- 深入理解ServletRequest与ServletResponse
- EQueue - 一个纯C#写的分布式消息队列介绍2
- RequestDispatcher
- 修改 Semantic UI 中对 Google 字体的引用
- 交互设计之Gestalt原则
- UGUI基本控件
- error: Error: No resource found that matches the given name (at 'layout_above' with value '@id/btnLayout').