题目描述:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
代码实现:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if( pRoot == nullptr || k <= 0 )
return nullptr;
stack<TreeNode*> nodes;
TreeNode* pointer;
pointer = pRoot;
// nodes.push(pointer);
int i = 0;
while( (nodes.size() != 0) || pointer )
{
while( pointer != nullptr )
{
nodes.push( pointer );
pointer = pointer->left;
}
if( !nodes.empty() )
{
pointer = nodes.top();
nodes.pop();
i++;
if( i == k )
return pointer;
pointer = pointer->right;
}
}
return nullptr;
}
};
首先拿到这道题,我有点蒙,想到了中序遍历,但是总是实现不了。最后还是去百度了中序遍历算法才写出来的。总结起来,还是对算法不熟,提醒自己要看一下深搜和广搜的前序、中序、后序的递归非递归实现了。
另外,在最后调试的时候,我总是只通过了3.75%的测试用例(当然,当时的程序不是这样)。我找了半天,觉得我写的没错啊。后来对照着答案自习看了下,发现有一个地方写的不一样。我的while循环的条件是
while( (nodes.size() != 0) && (i < k) )
答案是
while( (nodes.size() != 0) || pointer )
这两个地方的差别到底在哪里呢?
我想了下,感觉自己恍然大悟!哦!一开始就进不去这个循环,因为nodes是空的,好傻啊!那么把这个改掉肯定就没问题啦,我就在while循环的前面把最开始的pRoot给push进去,结果还是错了。。。。真是too young too simple
自以为找到了bug,呵呵!
我又想是哪里出现了问题,原来,按照测试用例,它有一步是将8出栈,这个时候pointer不为空但是栈是空的,所有又跳出循环,GG
所以那个循环条件应该那么写,既避免了栈空pointer不为空的情况,也避免了栈不空但pointer为空的情况(例如当pointer为7的右子树的时候),思维还是要严密啊,别人的判断条件可不是随便写写的,都是有原因滴!