6-4 The Kth Largest X in BST (30point(s)) (两种方法)

题目:传送门

 

法一:(投机取巧法)

题目的意思就是在一棵BST中找到一个数X,然后得到这个数是第几大的(千万不要理解成找第X个大的数了

然后我们就可以利用BST的特点来求解:中序遍历为有序序列

那么问题就转换成了在有序序列中找一个数,这时候可以暴力枚举,可以二分,想咋滴咋滴,反正就是能做了

Code:

int a[1000], cnt;             //a数组存储中序遍历的序列
void inOrder(BinTree T){                 //中序遍历,这个必须得会的吧!
	if(!T) return;       
	inOrder(T->Left);
	a[cnt++] = T->Key;
	inOrder(T->Right);
}

int KthLargest ( BinTree T, int X ){
	inOrder(T);                 //先走一波中序遍历,得到a数组
	for(int i = cnt - 1; i >= 0; i--)      //然后倒着枚举,因为a数组是升序的,而我们要找第k大的,所以倒着更符合逻辑,当然正着枚举也OK,也可以二分
		if(a[i] == X) return cnt - i;             //找到了就返回对应的次序
	return 0;              //没找到返回0
}

显然出题人的意思不是让你中序遍历然后求,虽然结果对了!!!

 

法二:递归做法

递归不太好解释,就直接上代码了,注释还是比较详细的:

int KthLargest ( BinTree T, int X ){
  	if(!T) return 0;                //没找到,返回0
	
  	if(T->Key == X){                //找到了,那么 该结点的排名 = 该结点后继的排名 + 1
  		BinTree temp = T->Right;      
  		if(!temp) return 1;           //不存在右子树,那么就是最大的
		while(temp->Left) temp = temp->Left;	   //找到后继
  		return KthLargest(T->Right, temp->Key) + 1;           //返回 后继的排名 + 1
	} 
    
	if(T->Key > X){                //大于X,就去左子树找
		int t = KthLargest(T->Left, X);           
		if(!t)  return 0;          //在左子树上没找到,就返回0
	    return t + KthLargest(T, T->Key);            //否则返回X  在左子树上的排名 + 当前根节点的排名
    } 
  	return KthLargest(T->Right, X);	             //小于X, 就去右子树上找(在右子树上的排名即为在整棵树上的排名)
}

 

今天又看到了lsq大佬的方法,详见 大佬解法

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值