【数据结构与算法 | 灵神题单 | 自顶向下DFS篇】力扣1022,623

1. 力扣1022:从根到叶的二进制之和

1.1 题目:

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。

  • 例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。

对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

返回这些数字之和。题目数据保证答案是一个 32 位 整数。

 

示例 1:

 

edb18e8e265df8d805bec5e2813bc4b0.png

输入:root = [1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

示例 2:

输入:root = [0]
输出:0

提示:

  • 树中的节点数在 [1, 1000] 范围内
  • Node.val 仅为 0 或 1 

1.2 思路:

dfs递归,使用列表来记录从根到叶子节点的路径。递归方法中参数k用来记录该节点在列表中的索引位置,便于到叶子节点的for循环计算。然后继续向左右子树递归,如果其左右子树都处理完了,那么就从列表中删除这个节点的值,

1.3 题解 :

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 全局变量sum记录这些数字之和
    int sum;
    // 用列表来记录从根节点到叶子节点走过的路径
    List<Integer> list = new LinkedList<>();
    public int sumRootToLeaf(TreeNode root) {
        dfs(root, 0);

        return sum;
    }
    // 参数列表里的k表示这个节点的值在列表中的索引位置
    private void dfs(TreeNode node, int k) {
        if(node == null){
            return;
        }
        list.add(node.val);
        // 如果是叶子节点,就把列表的二进制数字统计加起来
        if(node.left == null && node.right == null){
            int m = 1;
            for(int i = k; i >= 0; i--){
                sum += list.get(i)*m;
                m *= 2;
            }
            
        }
        // 继续递归
        dfs(node.left, k+1);
        dfs(node.right, k+1);
        // 处理完左右孩子节点后,就将该节点从列表中删除
        list.remove(k);
    }
}

代码稍微优化的一下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 全局变量sum记录这些数字之和
    int sum;
    // 用列表来记录从根节点到叶子节点走过的路径
    List<Integer> list = new LinkedList<>();
    public int sumRootToLeaf(TreeNode root) {
        dfs(root, 0);

        return sum;
    }
    // 参数列表里的k表示这个节点的值在列表中的索引位置
    private void dfs(TreeNode node, int k) {
        if(node == null){
            return;
        }
        list.add(node.val);
        // 如果是叶子节点,就把列表的二进制数字统计加起来
        if(node.left == null && node.right == null){
            int m = 1;
            for(int i = k; i >= 0; i--){
                sum += list.get(i)*m;
                m *= 2;
            }
        }else{
            // 继续递归
            dfs(node.left, k+1);
            dfs(node.right, k+1);
        }
        // 处理完左右孩子节点后,就将该节点从列表中删除
        list.remove(k);
        
    }
}

2. 力扣623:在二叉树中增加一行

2.1 题目:

给定一个二叉树的根 root 和两个整数 val 和 depth ,在给定的深度 depth 处添加一个值为 val 的节点行。

注意,根节点 root 位于深度 1 。

加法规则如下:

  • 给定整数 depth,对于深度为 depth - 1 的每个非空树节点 cur ,创建两个值为 val 的树节点作为 cur 的左子树根和右子树根。
  • cur 原来的左子树应该是新的左子树根的左子树。
  • cur 原来的右子树应该是新的右子树根的右子树。
  • 如果 depth == 1 意味着 depth - 1 根本没有深度,那么创建一个树节点,值 val 作为整个原始树的新根,而原始树就是新根的左子树。

示例 1:

 

59cae442312c951ba98b133c0591ae46.jpeg

输入: root = [4,2,6,3,1,5], val = 1, depth = 2
输出: [4,1,1,2,null,null,6,3,1,5]

示例 2

fc8f1463c5b546f599e082d217947344.jpeg

输入: root = [4,2,null,3,1], val = 1, depth = 3
输出:  [4,2,null,1,1,3,null,null,1]

 

提示:

  • 节点数在 [1, 104] 范围内
  • 树的深度在 [1, 104]范围内
  • -100 <= Node.val <= 100
  • -105 <= val <= 105
  • 1 <= depth <= the depth of tree + 1

2.2 思路:

dfs的思想,总体来说,增加一行有两种情况:

  • 在树中间增加一行。
  • 在树的最下层的叶子节点的再下一层增加一行。

第一种情况 ,比较好想到,通过dfs的参数k找到要处理的层级节点,然后处理新new的节点与该节点和父亲节点之间的关系。

第二种情况:此时node为null,跟第一种情况的代码几乎完全一样(就不需要处理new节点的孩子 节点的情况)。

2.3 题解:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode addOneRow(TreeNode root, int val, int depth) {
        // 特殊情况,提前判断即可
        if(depth == 1){
            TreeNode node = new TreeNode(val);
            node.left = root;
            return node;
        }
        dfs(null, root, depth, 1, val);
        return root;
    }
    // k表示该节点在树中的位置
    private void dfs(TreeNode parent, TreeNode node, int depth, int k, int val) {
        // 当遍历到叶子节点的左右孩子的时候,如果需要在这一层添加节点的话
        // 需要作额外操作,做完操作再返回
        if(node == null){
            // 比方说叶子节点在第三层,depth在第四层,那么需要在第四层new节点
            if(depth == k){
                if(parent.left == node){
                    node = new TreeNode(val);
                    parent.left = node;
                }else{
                    node = new TreeNode(val);
                    parent.right = node;
                }
            }
            return;
        }
        // node不为null的前提下,即对于一般节点的情况
        // 需要处理新new处理出来的节点与该节点和父亲节点
        // 三者之间的关系
        // 处理完直接返回
        if(k == depth){
            TreeNode p = new TreeNode(val);
            if(parent.left == node){
                p.left = node;
                parent.left = p;
            }else{
                p.right = node;
                parent.right = p;
            }
            return;
        }
        // 如果未到时候吗,则递归左右子树
        dfs(node, node.left, depth, k+1, val);
        dfs(node, node.right, depth, k+1, val);
    }
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/879841.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Uniapp的alertDialog返回值+async/await处理确定/取消问题

今天在使用uniui的alertDialog时&#xff0c;想添加一个确定/取消的警告框时 发现alertDialog和下面的处理同步进行了&#xff0c;没有等待alaertDialog处理完才进行 查询后发现问题在于 await 关键字虽然被用来等待 alertDialog.value.open() 的完成&#xff0c;但是 alertDi…

Linux操作系统 进程(3)

接上文 Linux进程优先级之后&#xff0c;我们了解到僵尸进程与孤儿进程的形成原因&#xff0c;既然是因为父进程没有接收子进程的退出状态导致的&#xff0c;那么我们该如何去获取子进程的退出状态呢&#xff1f;那本篇文章将围绕这个问题来解释进程。 环境 &#xff1a; vsco…

【C++】——多态详解

目录 1、什么是多态&#xff1f; 2、多态的定义及实现 2.1多态的构成条件 ​2.2多态语法细节处理 2.3协变 2.4析构函数的重写 2.5C11 override 和 final关键字 2.6重载—重写—隐藏的对比分析 3、纯虚函数和抽象类 4、多态的原理分析 4.1多态是如何实现的 4.2虚函数…

光伏场地建设规划 - 华为OD统一考试(E卷)

2024华为OD机试&#xff08;C卷D卷E卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 祖国西北部有一片大片荒地&#xff0c;其中零星的分布着一些湖泊&#xff0c;保护区&#xff0c;矿区;整体上常年光照良好&#xff0c;但是也有一些地区光照不太好。某电力公…

C++中模板的初级使用函数模板(刚刚接触模板概念的小白也能明白)

文章目录 模板分类函数模板函数模板的原理函数模板基本语法 —— typename 以及 class简单的函数模板多类型模板参数class 和 typename 的选择类模板 模板分类 模板的核心思想是让编译器在编译时生成适用于具体类型的代码&#xff0c;这个过程称为模板实例化。C 中的模板分为两…

Sublime Text 3 相关设置

打开设置 { “font_size”: 16, // 字体大小 “save_on_focus_lost”: true, // 自动保存 }

射击靶标检测系统源码分享

射击靶标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

【吊打面试官系列-MySQL面试题】LIKE 声明中的%和_是什么意思?

大家好&#xff0c;我是锋哥。今天分享关于【LIKE 声明中的&#xff05;和_是什么意思&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; LIKE 声明中的&#xff05;和_是什么意思&#xff1f; &#xff05;对应于 0 个或更多字符&#xff0c;_只是 LIKE 语句中的…

Amazon Bedrock 模型微调实践(二):数据准备篇

本博客内容翻译自作者于 2024 年 9 月在亚马逊云科技开发者社区发表的同名博客&#xff1a; “Mastering Amazon Bedrock Custom Models Fine-tuning (Part 2): Data Preparation for Fine-tuning” 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、…

Leetcode—322. 零钱兑换【中等】(memset(dp,0x3f, sizeof(dp))

2024每日刷题&#xff08;159&#xff09; Leetcode—322. 零钱兑换 算法思想 dp实现代码 class Solution { public:int coinChange(vector<int>& coins, int amount) {int m coins.size();int n amount;int dp[m 1][n 1];memset(dp, 0x3f, sizeof(dp));dp[0][…

Django ORM(多表)

文章目录 前言一、关联关系模型二、一对多写入数据二、多对多写入数据二、跨表查询1.查找test 标签的文章2.查找作者名为 test 的文章及标签 三、跨表删除 前言 表与表之间的关系可分为以下三种&#xff1a; 一对一: 一对一关系表示一个模型的每个实例与另一个模型的每个实例…

【字符函数】strcpy函数(字符串复制函数)+strcat函数(字符串追加)+strcmp函数(字符串比较)【笔记】

1.复制函数--------------strcpy函数 函数使用 char*strcpy&#xff08;char* destination, const char* source&#xff09; strcpy函数用于拷贝字符串&#xff0c;即将一个字符串中的内容拷贝到另一个字符串中&#xff08;会覆盖原字符串内容&#xff09;。它的参数是两个指…

Mysql梳理6——order by排序

目录 6 order by排序 6.1 排序数据 6.2 单列排序 6.3 多行排列 6 order by排序 6.1 排序数据 使用ORDER BY字句排序 ASC&#xff08;ascend&#xff09;:升序DESC(descend):降序 ORDER BY子句在SELECT语句的结尾 6.2 单列排序 如果没有使用排序操作&#xff0c;默认…

【HarmonyOS NEXT】DevEco快速实现真机截屏,并保存到电脑

点日志点照机图标选一个路径保存图片在ide中右键图片&#xff0c;点复制电脑随便找个位置保存图片https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-screenshot-V5

1-2.Jetpack 之 Navigation 跳转编码模板

一、Navigation 1、Navigation 概述 Navigation 是 Jetpack 中的一个重要成员&#xff0c;它主要是结合导航图&#xff08;Navigation Graph&#xff09;来控制和简化 Fragment 之间的导航&#xff0c;即往哪里走&#xff0c;该怎么走 2、Navigate 引入 在模块级 build.gra…

Datawhale------Tiny-universe学习笔记——Qwen(1)

1. Qwen整体介绍 对于一个完全没接触过大模型的小白来说&#xff0c;猛一听这个名字首先会一懵&#xff1a;Qwen是啥。这里首先解答一下这个问题。下面是官网给出介绍&#xff1a;Qwen是阿里巴巴集团Qwen团队研发的大语言模型和大型多模态模型系列。其实随着大模型领域的发展&a…

全同台加密综述

文章目录 一、FHE的定义与性质1、核心算法2、性质 二、构造思想三、全同态加密研究进展1、支持部分同态的 Pre-FHE 方案2、基于理想格的 第1代 FHE方案3、基于LWE的 第2代 FHE方案3、基于近似特征向量的 第3代 FHE方案4、支持浮点数运算的 第4代 FHE方案5、其他 FHE方案5.1、基…

数字化时代,住宅代理是怎样为企业赋能的?

在数字化时代&#xff0c;企业的发展也面临着转型&#xff0c;一方面是未知的挑战&#xff0c;一方面是不可多得的机遇。如何在全球市场中保持竞争力是企业要认真思考的问题。如果说主动寻找出路太过冒险&#xff0c;那不妨试试内省式的自我管理革新。代理服务器是一种中介服务…

TI DSP下载器XDS100 V2.0无法使用问题

前言 TI DSP下载器XDS100 V2.0用着用着会突然报Error&#xff0c;特别是你想要用Code Composer Studio烧录下载程序的时候 查看设备管理器&#xff0c;发现XDS100 V2.0的设备端口莫名其妙消失了 问了淘宝的厂家&#xff0c;他说TI的开发板信号可能会导致调试器通信信号中断&a…

软件安全最佳实践:首先关注的地方

尽管组织拥有大量可用的工具&#xff0c;但应用程序安全性仍然不足。 最近的数据显示&#xff0c;在过去四到五年中&#xff0c;软件供应链攻击同比增长了 600-700%&#xff0c;超过一半的美国企业在过去 12 个月中遭受过某种形式的软件供应链攻击。 为何应用程序安全工作未…