目录
1.剑指Offer
面试题54:二叉搜索树的第k大节点
题目描述:给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
思路:中序遍历
代码:
方法1:递归实现
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if(pRoot==nullptr||k<=0){
return nullptr;
}
return KthNodeCore(pRoot,k);
}
TreeNode* KthNodeCore(TreeNode* pRoot, int& k){
TreeNode* target=nullptr;
if(pRoot->left!=nullptr){
target=KthNodeCore(pRoot->left,k);
}
if(target==nullptr){
if(k==1){
target=pRoot;
}
k--;
}
if(target==nullptr&&pRoot->right!=nullptr){
target=KthNodeCore(pRoot->right,k);
}
return target;
}
};
注意:要在“TreeNode* KthNodeCore(TreeNode* pRoot, int& k)”语句中k前加&,否则会报错。
“if(pRoot==nullptr||k<=0)”判断条件应该是k<=0而不是k==0,并且用||连接。
class Solution {
int count = 0;
public:
TreeNode* KthNode(TreeNode* pRoot, unsigned int k)
{
if(pRoot){
TreeNode *ret = KthNode(pRoot->left, k);
if(ret) return ret;
if(++count == k) return pRoot;
ret = KthNode(pRoot->right,k);
if(ret) return ret;
}
return nullptr;
}
};
方法2:中序遍历所有节点放入数组,取出第k-1个元素。
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
//中序遍历的结果就是有序序列,第K个元素就是vec[K-1]存储的节点指针;
if(pRoot==NULL||k<=0) return NULL;
vector<TreeNode*> vec;
Inorder(pRoot,vec);
if(k>vec.size()){
return NULL;
}
return vec[k-1];
}
void Inorder(TreeNode* pRoot,vector<TreeNode*>& vec){
//中序遍历,将节点依次压入vector中
if(pRoot==NULL) return;
Inorder(pRoot->left,vec);
vec.push_back(pRoot);
Inorder(pRoot->right,vec);
}
};
面试题51:数组中的逆序对
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0 输出
7
思路:先把数组分割成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序。如果对排序算法很熟悉,我们不难发现这个过程实际上就是归并排序。
代码:
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.empty()||data.size()==0) return 0;
int len=data.size();
vector<int> copy;
for(int i=0;i&