1104. 二叉树寻路

地址:

力扣icon-default.png?t=M1L8https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree/

题目:

在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。

如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;

而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。

 

给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。

示例 1:

输入:label = 14
输出:[1,3,4,14]


示例 2:

输入:label = 26
输出:[1,2,6,10,26]
 

提示:

1 <= label <= 10^6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

对于满二叉树,每一个节点都可以对应一个二进制数

 示例:num = 14

需要经过的路径为: 14->4->3->1

 如果是正常的应该 走灰色路径,毕竟存在 2x, 2x+1 的关系

目前正好父节点是镜像关系,我们来看看如何通过二进制计算出镜像节点值

1. 子节点依旧存在 /2 = 父节点 的关系,所以通过 14 >> 1 的到正常 7

2. 观察 7 与 4 镜像关系,可见除了最高位不变,其余位取反

 

3. 4 >> 1 往上层走,依旧存在最高位不变,其余位取反关系

4. 3 >> 1 = 1 到达根节点,结束

所以我们寻路逻辑就是右移,保持最高位,然后取反 ,一直循环直到根节点

方法一、二进制位操作

1. 首先要计算出 10 进制数总共有多少位

2. 取二进制末尾 k 位的公式: num &= 1<<k - 1

        k 的左移后 - 1 相当于 1 移动到 k+1 位,然后 -1,保证 k 位全为 1

int countBit(int num)
{
	int bits = 0;
	
	while(num != 0)
	{
		bits++;
		num >>= 1;
	}
	
	return bits;	
}

int calNumbyBit(num, bits)
{
	num &= ( ( (1<<(bits-1) ) - 1) );
	num = ~num;
	num &= ( (1<<bits) - 1);
	
	return num;
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* pathInZigZagTree(int label, int* returnSize){
	int bits = countBit(label);
	int *arr = (int *)malloc(sizeof(int) * bits);
	*returnSize = bits;

	int i = bits -1;
	while(label != 1)	
	{
		arr[i] = label;
		label >>= 1;
		bits--;
        
		label = calNumbyBit(label, bits);
		i--;	
	}
    arr[i] = label;

    return arr;
}

查看更多刷题笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值