leecode 解题总结:230. Kth Smallest Element in a BST

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <stack>
using namespace std;
/*
问题:
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?

分析:给定一颗二叉搜索树,搜索第k小的元素。
中序遍历二叉搜索树,得到顺序排列的结果。第k小的元素,等于中序遍历第k个元素。
可以事先存储整个遍历结果,第k小的元素在O(1)时间就可以得到,但1次操作整体的时间复杂度
为O(n),后续都是O(1)

     4
   /   \
  2     6
 / \   / \
1   3 5   7

输入:
7(结点个数) 1(k)
4 2 6 1 3 5 7
7 2
4 2 6 1 3 5 7
7 3
4 2 6 1 3 5 7
7 4
4 2 6 1 3 5 7
7 5
4 2 6 1 3 5 7
7 6
4 2 6 1 3 5 7
7 7
4 2 6 1 3 5 7
输出:
1
2
3
4
5
6
7

关键:
1 存储依次中序遍历结果后,后续从数组中直接返回第k个小的元素
*/

 struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };

class Solution {
public:
	//中序遍历
	int inOrder(TreeNode* root , int k)
	{
		if(!root)
		{
			return 0;
		}
		_result.clear();
		TreeNode* current = root;
		stack<TreeNode*> nodes;
		TreeNode* node;
		while(!nodes.empty() || current)
		{
			if(current)
			{
				nodes.push(current);
				current = current->left;
			}
			else
			{
				node = nodes.top();
				_result.push_back(node->val);
				nodes.pop();
				if(node)
				{
					current = node->right;
				}
				else
				{
					current = NULL;
				}
			}
		}
		
		if(_result.empty() || k > _result.size())
		{
			return 0;
		}
		else
		{
			return _result.at(k - 1);
		}
	}

    int kthSmallest(TreeNode* root, int k) {
		if((!root) || k < 0)
		{
			return 0;
		}
        if(!_result.empty() && k <= _result.size())
		{
			return _result.at(k - 1);
		}
		else
		{
			int result = inOrder(root , k);
			return result;
		}
    }
private:
	vector<int> _result;//中序遍历结果
};

//构建二叉树,这里默认首个元素为二叉树根节点,然后接下来按照作为每个结点的左右孩子的顺序遍历
//这里的输入是每个结点值为字符串,如果字符串的值为NULL表示当前结点为空
TreeNode* buildBinaryTree(vector<string>& nums)
{
	if(nums.empty())
	{
		return NULL;
	}
	int size = nums.size();
	int j = 0;
	//结点i的孩子结点是2i,2i+1
	vector<TreeNode*> nodes;
	int value;
	for(int i = 0 ; i < size ; i++)
	{
		//如果当前结点为空结点,自然其没有左右孩子结点
		if("N" == nums.at(i))
		{
			nodes.push_back(NULL);
			continue;
		}
		value = atoi(nums.at(i).c_str());
		TreeNode* node = new TreeNode(value);
		nodes.push_back(node);
	}
	//设定孩子结点指向,各个结点都设置好了,如果但钱为空结点,就不进行指向
	for(int i = 1 ; i <= size ; i++)
	{
		if(NULL == nodes.at(i-1))
		{
			continue;
		}
		if(2 * i <= size)
		{
			nodes.at(i-1)->left = nodes.at(2*i - 1);
		}
		if(2*i + 1 <= size)
		{
			nodes.at(i-1)->right = nodes.at(2*i);
		}
	}
	//设定完了之后,返回根节点
	return nodes.at(0);
}

void deleteBinaryTree(TreeNode* root)
{
	if(!root)
	{
		return;
	}
	if(NULL == root->left && NULL == root->right)
	{
		delete root;
		root = NULL;
	}
	if(root)
	{
		deleteBinaryTree(root->left);
		deleteBinaryTree(root->right);
	}
}

void process()
{
	 vector<string> nums;
	 string value;
	 int num;
	 Solution solution;
	 vector<vector<string> > result;
	 int k;
	 while(cin >> num >> k )
	 {
		 nums.clear();
		 for(int i = 0 ; i < num ; i++)
		 {
			 cin >> value;
			 nums.push_back(value);
		 }
		 TreeNode* root = buildBinaryTree(nums);
		 int answer = solution.kthSmallest(root , k);
		 //打印二叉树中序结点值
		 cout << answer << endl;
		 deleteBinaryTree(root);
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值