剑指 Offer 第15天 搜索与回溯算法(中等)

news2025/1/9 15:44:55

目录

剑指 Offer 34. 二叉树中和为某一值的路径

剑指 Offer 36. 二叉搜索树与双向链表

剑指 Offer 54. 二叉搜索树的第k大节点


剑指 Offer 34. 二叉树中和为某一值的路径

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解法一】dfs

class Solution {
public:
    vector<vector<int>> res;
    vector<int> temp;
    void dfs(TreeNode* root, int target)
    {
        if(root)
        {
            temp.push_back(root->val);
            target-=root->val;
        }
        if(root->left==nullptr && root->right==nullptr && target==0)
        {
            res.push_back(temp);
            temp.pop_back();
            return;
        }
        if(root->left)
        {
            dfs(root->left, target);
        }

        if(root->right)
        {
            dfs(root->right, target);
        }
        temp.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int target) {
        if(root)dfs(root, target);
        return res;
    }
};

【解法二】上面的代码中间部分到达叶子结点加入一个return的原因是提前结束,提前结束了就不能走到下面pop的位置,所以需要把当前结点给pop出去

class Solution {
public:
    vector<vector<int>> res;
    vector<int> temp;
    void dfs(TreeNode* root, int target)
    {
        if(root == nullptr)return;
        temp.push_back(root->val);
        target-=root->val;
        if(root->left==nullptr && root->right==nullptr && target==0)
        {
            res.push_back(temp);
            //temp.pop_back();
            //return;
        }
            dfs(root->left, target);
            dfs(root->right, target);
        temp.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int target) {
        if(root)dfs(root, target);
        return res;
    }
};

剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解法一】创建一个新的头结点,然后利用二叉搜索树的特点,进行中序遍历,按照中序遍历的每个元素值来创建新结点,然后依次将这些新结点尾插到头结点后面。

class Solution {
public:
    Node* newhead = new Node(0);    //创建新的头结点,
    Node* cur = newhead;            //把后续中序遍历的结果依次尾插到新头结点后面
    void preoder(Node* root)
    {
        if(root==nullptr)return;
        preoder(root->left);

        Node* newnode = new Node(root->val);//创建newnode
        cur->right = newnode;   // 接入新的头结点中
        cur = cur->right;       // cur后移 处理下一个结点

        preoder(root->right);
    }
    Node* treeToDoublyList(Node* root) {
        preoder(root);  // 进行中序遍历
        if(newhead->right)
        {
            Node* prev = newhead->right;
            cur = newhead->right->right;    // 依次处理每个结点的left指向
            while(cur)
            {
                cur->left = prev;
                prev = prev->right;
                cur = cur->right;
            }
            prev->right = newhead->right;
            newhead->right->left = prev;
        }
        return newhead->right;
    }
};

【解法二】使用一个数组来存储中序遍历的结果,然后依次遍历数组,处理每个结点的前后指针

class Solution {
public:
    vector<Node*> res;
    void preoder(Node* root)
    {
        if(root==nullptr)return;
        preoder(root->left);
        res.push_back(root);    // 中序遍历 将结点尾插入数组
        preoder(root->right);
    }
    Node* treeToDoublyList(Node* root) {
        if(!root)return nullptr;
        preoder(root);
        for(int i = 0; i < res.size()-1; i++)
        {
            res[i]->right = res[i+1];    // 处理前后指向
            res[i+1]->left = res[i];
        }
        res[0]->left = res[res.size()-1];
        res[res.size()-1]->right = res[0];
        return res[0];
    }
};

【方法三】原地修改,直接dfs递归遍历每个结点,创建俩个指针,prev与head,当中序遍历到最左侧第一个结点时,让head指向该结点,将当前结点指向prev,然后让prev移动到当前结点位置,返回上一结点,然后prev的right指向cur,cur的left也指向这个prev,然后继续一起往后走。

class Solution {
public:
    Node *prev, *head;
    void dfs(Node* cur)
    {
        if(!cur)return;
        dfs(cur->left);
        if(prev)prev->right = cur;
        else head = cur;
        cur->left = prev;
        prev = cur;
        dfs(cur->right);
    }
    Node* treeToDoublyList(Node* root) {
        if(!root)return nullptr;
        dfs(root);
        prev->right = head;
        head->left = prev;
        return head;
    }
};

剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 4

【解法一】先序遍历放入数组中,返回size-k下标元素值

class Solution {
public:
    vector<int> res;
    void Inoder(TreeNode* root)
    {
        if(!root)return;
        Inoder(root->left);
        res.push_back(root->val);
        Inoder(root->right);
    }
    int kthLargest(TreeNode* root, int k) {
        Inoder(root);
        return res[res.size()-k];
    }
};

【解法二】

class Solution {
public:
    int res = 0, k;
    void Inoder(TreeNode* root)
    {
        if(!root)return;
        Inoder(root->right);
        if(k==0)return;
        if(--k==0)
        {
            res = root->val;
            return;
        }
        Inoder(root->left);
    }
    int kthLargest(TreeNode* root, int k) {
        this->k = k;
        Inoder(root);
        return res;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【懒狗福音】设置Bios电源自启实现远程办公

目录前言正文需求分析开始实现需求1需求2总结前言 今年寒假升级了下家里台式机的配置&#xff0c;已经很能满足我的生产力需求。 尽管我是按着MATX主机的方向配的&#xff0c;选择的机箱也是净重较轻的铝合金材质&#xff0c;机身自带提手也还算便捷。 但是装配完毕后它的整…

前端开发:JS中数组常用方法汇总

前言 在前端开发中关于数组的使用想必前端开发者并不陌生&#xff0c;尤其是在处理业务逻辑的时候&#xff0c;从后端获取的数据类型中数组类型基本占到70%的比例&#xff0c;所以与其说是处理数据&#xff0c;不如说是处理数组&#xff0c;虽然说的有点夸张&#xff0c;前端实…

vue文件导出/下载

const blob new Blob([res.data]);const elink document.createElement(a);elink.download 导出数据.xlsx;elink.style.display none;elink.href URL.createObjectURL(blob);document.body.appendChild(elink);elink.click();URL.revokeObjectURL(elink.href);document.bo…

使用Coding管理项目代码记录

直接开门见山 一、创建项目 进入coding登录后&#xff0c;找到项目菜单&#xff0c;然后点击创建项目 二、创建代码仓库 进入项目中&#xff0c;针对不同需要创建代码仓库。大项目或者前后端分离分开开发的可以创建不同的代码仓库。 三、创建代码仓库与本地关联 项目管…

Java岗面试题--Java基础(日积月累,每日三题)

目录面试题一&#xff1a;JDK、JRE、JVM之间的区别面试题二&#xff1a;hashCode()与equals()之间的关系追问&#xff1a;为什么重写 equals() 就一定要重写 hashCode() 方法&#xff1f;面试题三&#xff1a;String、StringBuffer、StringBuilder的区别追问一&#xff1a;Stri…

vulfocus靶场通关(目录遍历)

uWSGI 目录穿越&#xff08;CVE-2018-7490&#xff09; uWSGI是一款Web应用程序服务器&#xff0c;它实现了WSGI、uwsgi和http等协议&#xff0c;并支持通过插件来运行各种语言,uWSGI 2.0.17之前的PHP插件&#xff0c;没有正确的处理DOCUMENT_ROOT检测&#xff0c;导致用户可以…

【运维】通过gotty实现网页代理访问服务器及K8S容器操作实践

Gotty 是Golang编写的可以方便的共享系统终端为web应用&#xff0c;是一个灵活强大的通过web访问终端的工具。本文将主要通过搭建Gotty实现对K8S容器的访问操作&#xff0c;开发如果想要正常的进行容器访问以及测试环境代码调试&#xff0c;最好是搭建一套与运维环境隔离的应用…

Gadget驱动程序框架

Gadget驱动程序框架 文章目录Gadget驱动程序框架参考资料&#xff1a;一、 怎样理解Gadget框架二、从硬件软件角度理解Gadget框架2.1 底层硬件操作_UDC驱动2.2 上层软件操作三、 从构造描述符的角度理解Gadget框架致谢参考资料&#xff1a; Linux下USB gadget设备详解Linux us…

Linux常用命令——quotaon命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) quotaon 激活Linux内核中指定文件系统的磁盘配额功能 补充说明 quotaon命令用于激活Linux内核中指定文件系统的磁盘配额功能。执行quotaon指令可开启用户和群组的才磅秒年空间限制&#xff0c;各分区的文件系统…

STM32——I2C外设总线

文章目录一、I2C外设简介二、I2C框图三、I2C基本结构四、主机发送五、主机接收六、I2C的中断请求七、软件/硬件波形对比八、硬件I2C读写MPU6050电路设计关键代码状态监控函数一、I2C外设简介 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、起始终止条…

Go语言jwt无感刷新以及解决SSO单点登录限制

前言 为什么使用JWT&#xff1f; Jwt提供了生成token以及token验证的方法&#xff0c;而token是一种不用存储在服务端&#xff0c;只需要由用户携带即可实现认证的一种方式。在介绍JWT之前&#xff0c;我们也应该先了解cookie和session。 Cookie和Session 为每一位用户设定…

PLSQL Developer 代码助手卡顿优化

支持付费优化 原因分析 代码助手卡顿来源于&#xff08;不考虑网络和软件版本等影响&#xff09; A.从已连接的数据库的数据字典中&#xff0c;读取该表的列信息B.将读取到的列信息返回到plsql编辑器&#xff0c;并进行字符处理&#xff0c;然后显示如何优化B 这个勾勾是维…

【GPLT 二阶题目集】L2-034 口罩发放

为了抗击来势汹汹的 COVID19 新型冠状病毒&#xff0c;全国各地均启动了各项措施控制疫情发展&#xff0c;其中一个重要的环节是口罩的发放。 某市出于给市民发放口罩的需要&#xff0c;推出了一款小程序让市民填写信息&#xff0c;方便工作的开展。小程序收集了各种信息&#…

redis的配置文件

目录 介绍 1. 单位的设置方式 2. 可以包含其他文件内容 3. 网络配置相关 4. 通用 5. 安全 6. 限制 redis的配置文件名为redis.conf&#xff0c;一般会安装在/etc目录下。 如果找不到该文件可以使用find命令查找。 find . -name redis.conf 介绍 1. 单位的设置方式 只支持字…

client-go监听apiserver,监听http2逻辑分析

前言 最近做项目&#xff0c;需要写一个controller&#xff08;k8s的插件&#xff09;&#xff0c;需要从k8s的apiserver取数据&#xff0c;就用了自带的client-go&#xff0c;但是client-go是怎么从apiserver获取数据的一直没有研究过&#xff0c;只是看网上&#xff0c;看官…

Hudi系列10:Flink流式插入

文章目录流式插入概述一. Hudi流式插入案例1(datagen)1.1 准备工作1.2 源端准备1.3 目标端表准备1.4 ETL准备1.5 数据验证1.6 通过SPARK SQL查看数据二. Hudi流式插入案例2(Kafka)2.1 准备工作2.2 源端准备2.2.1 创建kafka的topic (hudi_flink)2.2.2 Flink SQL Client消费kafka…

卷积神经网络中的权值共享和局部连接

卷积神经网络中的权值共享和局部连接卷积神经网络的两大特点权值共享全连接卷积神经网络的两大特点 权值共享&#xff0c;就是输入一张图&#xff0c;用一个filter去扫这张图&#xff0c;filter里面的数就叫权重&#xff0c;这张图每个位置都是被同样的filter扫的&#xff0c;…

Flink官方例子解析:WordCount

1. 简介 今天介绍的是官方子项目flink-examples-streaming里面的WordCount例子。 WordCount &#xff0c;中文&#xff1a;单词统计&#xff0c;是大数据计算常用的例子。 2. WordCount需要实现的功能 监听指定目录下的文件&#xff0c;读取文件的文本内容&#xff1b;如果未…

Python继承机制及其使用

Python 类的封装、继承、多态 3 大特性&#xff0c;前面章节已经详细介绍了 Python 类的封装&#xff0c;本节继续讲解 Python 类的继承机制。继承机制经常用于创建和现有类功能类似的新类&#xff0c;又或是新类只需要在现有类基础上添加一些成员&#xff08;属性和方法&#…

RASP技术进阶系列(三):重大漏洞自动化热修复

在上篇文章《RASP技术进阶系列&#xff08;二&#xff09;&#xff1a;东西向Web流量智能检测防御》中提到&#xff0c;在企业日常安全运营以及HW场景下&#xff0c;应用漏洞攻击应急响应和恶意流量溯源分析是安全团队的重点工作。在恶意流量溯源方面&#xff0c;指向攻击来源的…