LeetCode 1104. 二叉树寻路 [java实现]

一、问题描述

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

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

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

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

二、测试数据

示例 1:
输入:label = 14
输出:[1,3,4,14]
示例 2:
输入:label = 26
输出:[1,2,6,10,26]
提示:
1 <= label <= 10^6

三、解题思路

​ 利用 偶不变,奇变 将路径从目标逐渐向根节点求解,结果倒置即可(2^0 ~ 2^layer)

存储由于是倒置的,可利用 栈(ArrayDeque)数组(数组个数和数组顺序已确定,个数为 layer+1

经研究得数组所使用内存较小,故使用数组

解题步骤:

  • 先求层数 layer :根据完全二叉树每棵树节点数都为 2^n
  • 将路径从目标逐渐向根节点求解:
    • 若层数为偶不变,为奇则转换为对称点(由数学得对称点为 truth = 3*(int)Math.pow(2,exp) -1 - label
    • 求完正确值 truth ,转为父节点求解(label = label/2)此时不考虑转换,因为正确值会转换
    • 交换转换 isChange = !isChange
//具体循环如下:
		for(int exp = layer,truth = 0;exp>=0;exp--){
                if(isChange){
                    truth = 3*(int)Math.pow(2,exp) -1 - label;
                }else{
                    truth = label;
                }
                if(exp!= layer){
                    number[exp] = truth;
                }            
                label = label/2;                                                               
                isChange = !isChange;              
            }

四、java实现

class Solution {
    public List<Integer> pathInZigZagTree(int label) {

        List<Integer> result = new ArrayList<>();

        if(label == 1){
            result.add(1);           
        }else{

            int layer = 0;
            for(int number = label;;layer++){               
                number -= (int)Math.pow(2,layer);
                if(number <= 0){
                    break;
                }               
            }

            int[] number = new int[layer+1];
            number[layer] = label;

            boolean isChange = false;//偶数不变
            for(int exp = layer,truth = 0;exp>=0;exp--){
                if(isChange){
                    truth = 3*(int)Math.pow(2,exp) -1 - label;
                }else{
                    truth = label;
                }
                if(exp!= layer){
                    number[exp] = truth;
                }            
                label = label/2;                                                               
                isChange = !isChange;              
            }

            for(int num:number){
                result.add(num);
            }        
        }
        return result;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值