笔试强训Day11

文章介绍了在特定二叉树结构中寻找两个节点最近公共祖先(LCA)的高效算法,利用二叉树的编号规则实现O(logN)的时间复杂度。同时,还提及了如何处理非二叉树结构和求解最大连续bit数的问题,同样保持了O(logn)的时间复杂度和O(1)的空间复杂度。
摘要由CSDN通过智能技术生成

T1:二叉树

链接:二叉树_牛客题霸_牛客网 (nowcoder.com)​​​​​​​s

题意:给你一颗二叉树,求俩个点的最近公共祖先(LCA)

因为比较特殊,树是一颗二叉树,二叉树的编号很特殊,学过线段树的都知道,假设当前点是x,那俩个儿子的编号就是2*x和2*x+1,父节点的编号是x/2; 

所以求LCA就只要让一个点往父节点跳(每次选编号最大的点跳)

时间复杂度:O(logN)

#include<iostream>
using namespace std;
int a,b;
int main()
{
	while(cin>>a>>b){
        while(a!=b){
            if(a>b)a/=2;
            else b/=2;
         }
	    cout<<a<<endl;
    }
	return 0;
}

 如果题目不是二叉树呢,并且编号不是这么有规律,如下图

这时阁下应当如何应对呢?

hhh,我选择掏出打ACM时候用的LCA板子

void dfs(int u, int fa)
{
	for (int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		if (j == fa)continue;
		dis[j] = dis[u] + 1;
		f[j][0] = u;
		for (int k = 1; (1 << k) <= dis[j]; k++) {
			f[j][k] = f[f[j][k - 1]][k - 1];
		}
		dfs(j, u);
	}
}

int lca(int a, int b)
{
	if (dis[a] < dis[b])swap(a, b);
	int d = dis[a] - dis[b];
	for (int i = 0; d; i++) {
		if (d & 1)a = f[a][i];
		d /= 2;
	}
	if (a == b)return a;
	for (int i = 21; i >= 0; i--) {
		if (f[a][i] != f[b][i]) {
			a = f[a][i];
			b = f[b][i];
		}
	}
	return f[a][0];
}

T2:求最大连续bit数

链接:求最大连续bit数_牛客题霸_牛客网 (nowcoder.com)

描述

求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1

数据范围:1≤n≤500000 

进阶:时间复杂度:O(logn) ,空间复杂度:O(1) 

#include<iostream>
using namespace std;
int n;
int main()
{
	cin>>n;
	int ans=0;
	int cnt=0;
	while(n){
		int k=n%2;
		if(k==1)cnt++;
		else cnt=0;
		ans=max(cnt,ans);
		n/=2;
	}
	cout<<ans<<endl;
	return 0;
}
思想很简单, 取出二进制的每一位,判断是1还是0,是1的话个数+1,否则变为0。然后与ans答案取最大值
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值