AcWing 49. 二叉搜索树与双向链表(前驱后继+中序遍历)

1025 - 链表动态查前驱和后继- 邻值查找(CH1301) 传送门 牢骚 看到这种题,绝对的平衡树乱搞 但我需要练习链表啊 昨天偷懒贴了ldx的读优,结果他又没有加负数,气…… 分析 将A数组排序后,建立链表 那么Ai在链表中的pre和nxt就分别对应其前驱和后继 从后往前查,查完后就删除这个点(因为题目要求是1<=j<i1<=j<i1<=j<i) 删除的话,就直接把 i 的nxt置为... 阅读详情

1.利用前驱后继

对于一个二叉树,可以将其分为左子树、根节点和右子树三部分。根据题目要求可知将BST化为一个排好序的双向链表实际上就是将其中序遍历序列对应的各个节点连接起来。同时还可以知道若根的左右子树非空,则根节点在链表中的前驱结点一定在其左子树中,后继结点一定在其右子树中。那么可以先找到并标记根节点的前驱和后继,然后连接。同时递归执行这一过程便能达到要求。

具体代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *findPreNode(TreeNode *root){
        TreeNode *p = root;
        if(p -> left){
            p = p -> left;
            while(p -> right) p = p -> right;
            return p;
        }
        else return NULL;
    }
    
    TreeNode *findSuccNode(TreeNode *root){
        TreeNode *p = root;
        if(p -> right){
            p = p -> right;
            while(p -> left) p = p -> left;
            return p;
        }
        else return NULL;
    }
    
    TreeNode *change(TreeNode * root){
        TreeNode *p = findPreNode(root); //记录前驱节点指针
        TreeNode *q = findSuccNode(root); //记录后继节点指针
        if(root -> left) change(root -> left);
        if(root -> right) change(root -> right);
        //将当前节点分别与其前驱节点和后继节点相连
        root -> left = p;
        if(p) p -> right = root;
        root -> right = q;
        if(q) q -> left = root;
        return root;
    }
    
    TreeNode* convert(TreeNode* root) {
        if(!root) return NULL;
        change(root);
        while(root -> left) root = root -> left;
        return root;
    }
};

2.中序遍历

可以发现对于一棵BST而言,中序遍历的当前节点与将要回溯的节点之间就是双向链表中相邻的关系。因此可以考虑通过中序遍历来直接完成BST到链表的转化。

具体代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *change(TreeNode *root, TreeNode *&head, TreeNode *&tail){
        if(!root) return NULL;
        change(root -> left, head, tail);
        if(!head){
            head = tail = root;
        }
        else{
            root -> left = tail;
            tail -> right = root;
            tail = root;
        }
        change(root -> right, head, tail);
        return head;
    }

    TreeNode* convert(TreeNode* root) {
        TreeNode *head = NULL, *tail = NULL; //注意这里要么在传参时使用指针引用要么将head和tail声明为全局变量
        return change(root, head, tail);
    }
};

 

学习十八-UJA107xA简介及移植-0 目录 1、UJA107xA系列手册 1、介绍 2.2.1 BAT引脚功能 2.4.1 V1、V2稳压器 2.5.1 CAN收发器 3.1 Startup Operation 3.2 Normal Operation 5.1 Attached Files 5.2 NXP UJA107xA Example Software 6、main() 1、UJA107xA系列手册 看完手册关于使用还是没有头绪的,只是想SPI发送指令将V2驱动起来,进而驱动起来CAN收... 阅读详情

相关推荐

Arduino MLX90393磁力计驱动库:高精度三轴霍尔传感器开发指南

三轴霍尔效应磁力计是嵌入式系统中实现无接触角度检测、电子罗盘与电流传感的核心器件。其工作原理基于霍尔电压随外磁场矢量变化的物理特性,通过I²C接口输出高分辨率(16/20-bit)XYZ轴原始数据,并集成温度补偿与数字滤波功能。技术价值体现在确定性响应、低功耗(典型0.5 μA待机)及强抗干扰能力,适用于电池供电设备与实时操作系统环境。典型应用场景包括电机位置反馈、永磁体旋转角度解算、工业编码器和地磁导航。本库专为Arduino生态优化,深度封装MLX90393寄存器协议与自校准流程,同时兼容STM32、E

weixin_29363791的博客 642

LeetCode 426. 将二叉搜索树转化为排序的双向链表(BST中序循环遍历)

文章目录1. 题目2. 解题 1. 题目 将一个 二叉搜索树 就地转化为一个 已排序的双向循环链表 。 对于双向循环列表,你可以将左右孩子指针作为双向循环链表的前驱和后继指针,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。 特别地,我们希望可以 就地 完成转换操作。 当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。 还需要返回链表中最小元素的指针。 示例 1: 示例 2: 输入:root = [2,1,3] 输出:[1,2,3] 示例 3: 输入:root

Michael是个半路程序员 2020

MCNP 减方差技巧(最全)

MCNP的减方差技巧,核心在于不显著增加计算时间的前提下,通过修改模拟过程来降低结果的统计误差。尤其适用于,这类问题中粒子很难到达探测器区域,直接模拟效率极低栅元重要性是常用的减方差技巧,该方法主要对计算模型的不同区域定义不同的重要性数值。当粒子从重要性低的区域废物重要性高的区域,产生更多粒子,增大统计量;当从重要性高的区域进入重要性低的区域,会进行,增快计算效率。n= 中子,N;光子,P;电子 Exi= 栅元i的重要性I=栅元总数项目IMP卡是必须的,除非使用了WWN卡如果粒子进入0。

chencheng1127的博客 926

AcWing 49 二叉搜索树与双向链表

题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。 要求不能创建任何新的结点,只能调整树中结点指针的指向。 注意: 需要返回双向链表最左侧的节点。 例如,输入下图中左边的二叉搜索树,则输出右边的排序双向链表。 分析: 题目要求我们将BST的中序遍历序列练成一个双向链表。可以看见,BST的垂直投影恰好就是有序的,对于链表中任一个结点,其前驱结点就是中序序列的前一...

昂昂累世士的博客 207

UVM入门与进阶学习笔记17——寄存器模型(3)

目录寄存器模型的常规方法mirror、desired和actual valueprediction的分类自动预测显式预测uvm_reg的访问方法mem与reg的联系和差别内建(built-in)sequences寄存器模型内建序列存储模型内建序列寄存器健康检查寄存器应用场景寄存器检查功能覆盖率概述覆盖率自动收集模式覆盖率外部事件触发收集 寄存器模型的常规方法 mirror、desired和actual value 在应用寄存器模型时,除了利用它的寄存器信息,也会利用它跟踪寄存器的值。 寄存器模型中的每

weixin_41979380的博客 7536

手把手教你学SOC芯片架构--NoC(片上网络,Network on Chip)全方位解析

​、​。

MHD0815的博客 864

问题 C: DS双向链表—前驱后继

问题 C: DS双向链表—前驱后继 时间限制: 1 Sec 内存限制: 128 MB 题目描述 在双向链表中,A有一个指针指向了后继节点B,同时,B又有一个指向前驱节点A的指针。这样不仅能从链表头节点的位置遍历整个链表所有节点,也能从链表尾节点开始遍历所有节点。 对于给定的一列数据,按照给定的顺序建立双向链表,按照关键字找到相应节点,输出此节点的前驱节点关键字及后继节点关键字。 输入 第一行两个正整数n(代表节点个数),m(代表要找的关键字的个数)。 接下来输入n个整数为关键字key(数据保证关键字在数列

elapse_的博客 1027

【项目实战】DevOps制品管理之JFrog Artifactory介绍

JFrog Artifactory是一款领先的二进制软件制品仓库管理工具,由JFrog公司开发。

奶爸的编程之路,也就一周冷个三天 1354

二查排序树的基本操作(插入,删除,找前驱与后继)

// Binary-Search-Tree.cpp : Defines the entry point for the console application. //最近要面试,想自己写写这类算法的代码,加深印象 #include "stdafx.h" //参考算法导论的伪代码编写 //有错误的地方,恳请大家批评指正,thx; typedef struct Node { int val; N

Dream 1216

XDMA流传输模式

XDMA 流传输模式(Streaming DMA)​ 是 Xilinx FPGA 通过 PCIe 与主机进行 ​实时流式数据传输 的核心机制,

浩瀚之水的专栏 3435

【38】OpenCV C++实战篇——基于多项式插值的亚像素边缘定位算法

亚像素边缘定位算法实现 本文介绍了一种基于多项式插值的亚像素边缘定位算法,用于提高图像边缘检测的精度。文章首先分析了传统像素级边缘检测方法(如Canny、Sobel)的局限性,指出其在测量应用中的精度不足问题。 算法核心 梯度计算:使用8个方向模板进行卷积运算生成梯度图像 亚像素定位:采用多项式插值方法改进边缘定位精度 实现步骤: 生成8个方向的卷积模板(0°、45°、90°等) 利用filter2D函数计算各方向梯度 通过归一化处理显示梯度图像 代码特点 提供完整的C++实现代码 包含模板生成、梯度计算和

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1099

AcWing解题目录(C++)

# 试题名称 思想方法 难度 试题来源 1 A+B 简单 AcWing 2 01背包问题 简单 3 完全背包问题 简单 4 多重背包问题I 简单 5 多重背包问题II 中等 6 多重背包问题...

Zee_Chao的博客 900

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

AcWing 34. 链表中环的入口结点(快慢指针赛跑+地址映射)

1.快慢指针赛跑 这是一个做起来很巧妙的算法,而且这个方法既不会改变原链表的结构,又不会需要额外的空间。 具体的操作是:从头结点开始,令快指针每次移动两个单位,慢指针每次移动一个单位。如果链表有环则两个指针必定会在环上的某一个位置相遇。此时令快指针重回起点,然后让两个指针同时每次移动一个单位,当两个指针再次相遇时(必定会相遇),相遇的结点恰好就是环的入口结点。 证明如下: 假设链表...

Zee_Chao的博客 1493

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

AcWing 21. 斐波那契数列(迭代算法(或DP算法))

斐波那契数列的求法有很多种,这里只列举一种最简单的方法。我们先假设斐波那契数列是如下排列的: 下标 0 1 2 3 4 5 …… 数据 0 1 1 2 3 5 …… 我们先设置两个变量f和g,并分别初始化为0和1以代表第0号元素和第1号元素。然后我们可以很容易地发现,只要不断重复进行如下操作 f ...

Zee_Chao的博客 864

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

AcWing 1.A+B

具体代码如下: #include <iostream> using namespace std; int main() { int a, b; cin >> a >> b; cout << a+b; return 0; }

Zee_Chao的博客 650

AcWing 23. 矩阵中的路径(DFS)

这是一道比较经典的深度优先搜索问题。首先,记录下每个字符串的起点位置。然后从每个位置开始进行深度优先搜索。 具体代码如下: class Solution { public: int dx[4] = {0, 0, -1, 1}; int dy[4] = {-1, 1, 0, 0}; bool dfs(vector<vector<char>...

Zee_Chao的博客 551

AcWing 51. 数字排列(DFS(有重复排列+无重复排列))

OJ上这道题的描述并不清晰。实际上,它的要求是输出所有“不重复的排列方式”。 1.next_permutation()(无重复排列) 要解决数组无重复排列的问题,那么这个方法是再合适不过的了。在使用这个函数前注意要引入<algorithm>头文件并且为了保证可以枚举所有情况要实现对数组进行“由小到大”的排序。 具体代码如下: class Solution { public...

Zee_Chao的博客 515

AcWing 14. 不修改数组找出重复的数字(分治法)

如果不将思考题考虑在内的话,那么AcWing 13.找出数组中重复的数字中的方法1的代码是可以完全移植过来的。这里不再赘述。不过,由于这道题的样例里面不存在含有超出范围的数据以及全部数据均出现一次的情况,因此代码还可以进一步简化。 简化后的具体代码如下: class Solution { public: int duplicateInArray(vector<int>...

Zee_Chao的博客 494

AcWing 13.找出数组中重复的数字(循环交换)

1.方法1 简单来说就是开辟一个空间为n的向量用来做数字出现次数的统计。由于题目只要求返回任意一个重复的数字,因此只需遍历统计向量找到首个记录出现次数大于1的数字即可。 具体代码如下: class Solution { public: int duplicateInArray(vector<int>& nums) { int n = nums...

Zee_Chao的博客 490

AcWing 15. 二维数组中的查找(非递归算法和递归算法)

1.非递归算法 观察此二维数组(以下称为“矩阵”),可以发现该矩阵的副对角线上的每一个元素均满足一个规律,那就是其左侧在同一行的元素均比其小,下侧在同一列的元素均比其大。于是,从副对角线入手进行查找就可以通过一次比较操作排除一整行和一整列的元素。从而大幅缩短时间开销。具体操作就是,当前位置元素如果等于目标元素则直接返回true,小于目标元素则将遍历指针下移一个单位,大于目标元素则将遍历指针左...

Zee_Chao的博客 467

AcWing 27. 数值的整数次方

1.方法1 根据题意只需要按常规的循环处理就行了。 具体代码如下: class Solution { public: double Power(double base, int exponent) { int n = abs(exponent); //取绝对值可以简化代码,等输出时再判断是否取倒数返回 double ans = 1.; ...

Zee_Chao的博客 416

AcWing 16. 替换空格

具体代码如下: class Solution { public: string replaceSpaces(string &str) { string ans; for(auto &e: str){ if(e == ' ') ans += "%20"; else ans += e; ...

Zee_Chao的博客 410

AcWing 26. 二进制中1的个数

1.方法1 容易理解的方法就是判断二进制最低位是否为1,然后计数器加一再将数据右移1位,直到数据变成0。需要注意的是,输入数据可能是负数。负数在右移时最高位会持续补1,这样的话程序会进入死循环。因此需要将输入数据强制类型转换为无符号整数,使得其右移时最高位补0(相关知识参考计算机组成原理的内容)。这里由于我们只关心输入数据的二进制表示,所以不必担心强制类型转换会带来问题。 由于每一次右移都...

Zee_Chao的博客 408

AcWing 45. 之字形打印二叉树(双栈法+reverse方法)

1.双栈法 根据经验,我们可以发现这道题需要对层次遍历的模板进行一定的改动。如果我们将根节点所在层定义为第0层,可以发现凡是偶数层都是从左往右打印,而奇数层却恰好相反。考虑到下一层与上一层节点的关系以及他们的相反输出次序,可以试着引入栈来进行反向输出的操作。那么问题来了,要怎么去设计对栈的控制呢? 这里的方案是引入两个栈,一个负责偶数层节点,记作stack0,另一个负责奇数层的,记作sta...

Zee_Chao的博客 402
上一篇: AcWing 48. 复杂链表的复刻(地址映射+原地复刻)
下一篇: AcWing 51. 数字排列(DFS(有重复排列+无重复排列))
Zee_Chao
博客等级 码龄11年 168粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值