笔试强训Day11

T1:二叉树

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

笔试强训Day11_第1张图片

笔试强训Day11_第2张图片

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

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

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

时间复杂度:O(logN)

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

 如果题目不是二叉树呢,并且编号不是这么有规律,如下图笔试强训Day11_第3张图片

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

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) 

笔试强训Day11_第4张图片

#include
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<
思想很简单, 取出二进制的每一位,判断是1还是0,是1的话个数+1,否则变为0。然后与ans答案取最大值

你可能感兴趣的:(笔试强训,算法,数据结构)