【LeetCode & 剑指offer刷题】树题16：Kth Smallest Element in a BST

【LeetCode & 剑指offer 刷题笔记】目录（持续更新中...）

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.
Example 1:
Input: root = [3,1,4,null,2], k = 1
3
/ \
1   4
\
2
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3   6
/ \
2   4
/
1
Output: 3
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?

C++

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/

/*

BST中序遍历之后为从小到大排列

*/
class Solution
{
public:
int kthSmallest(TreeNode* root, int k)
{
vector<int> nodes;
inorder(root, nodes);
return nodes[k-1];
}

void inorder(TreeNode* root, vector<int>& nodes)
{
if(root == nullptr) return; //递归的出口

inorder(root->left, nodes);
nodes.push_back(root->val);
inorder(root->right, nodes);
}
};

/*

*/
class Solution
{
public:
int kthSmallest(TreeNode* root, int k)
{
int cnt = 0;
stack<TreeNode*> s;
TreeNode *p = root;
while (!s.empty() || p)
{
if(p) //左结点不为空时
{
s.push(p);   //入栈

p = p->left; //指向下一个左结点
}
else //左结点为空时
{
p = s.top();
cnt++; //统计数目（遍历到了要访问的父结点）
if (cnt == k) return p->val;
s.pop();

p = p->right;  //指向右结点
}

}
return 0;
}
};
/*

*/
class Solution
{
public:
int kthSmallest(TreeNode* root, int k)
{
int cnt = count(root->left);
if (k <= cnt)
{
return kthSmallest(root->left, k);
}
else if (k > cnt + 1)
{
return kthSmallest(root->right, k - cnt - 1); //注意此处变为k - (cnt-1)
}
else
return root->val;
}
int count(TreeNode* node)
{
if (!node) return 0;
return 1 + count(node->left) + count(node->right);
}
};
/*

*/

class Solution
{
private:
struct MyTreeNode
{
int val;
int count;
MyTreeNode *left;
MyTreeNode *right;
MyTreeNode(int x) : val(x), count(1), left(NULL), right(NULL) {}
};

public:
int kthSmallest(TreeNode* root, int k)
{
MyTreeNode *node = build(root);
return helper(node, k);
}

MyTreeNode* build(TreeNode* root)
{
if (!root)
return NULL;
else
{
MyTreeNode *node = new MyTreeNode(root->val); //count在构造函数中被初始化为1
node->left = build(root->left);
node->right = build(root->right);
if (node->left) node->count += node->left->count; //统计数量
if (node->right) node->count += node->right->count;

return node;
}
}

int helper(MyTreeNode* node, int k)
{
if (node->left)
{
int cnt = node->left->count; //左结点存储了当前结点左子树的所有结点个数
if (k <= cnt)
return helper(node->left, k);
else if (k > cnt + 1)
return helper(node->right, k - 1 - cnt);
else
return node->val;
}
else
{
if (k == 1)
return node->val;
else
return helper(node->right, k - 1);

}
}
};

posted @ 2019-01-05 19:50  wikiwen  阅读(247)  评论(0编辑  收藏