左神基础算法笔记-四

西门子S7-1200与FUNUC机器人MODBUS TCP通信 PLC与机器人通讯 阅读详情

1. 二叉树先序、中序、后序遍历的非递归实现

先序遍历:使用栈实现,栈中先压入二叉树根节点,然后循环以下过程,先弹出一个节点,随后压入该节点的右孩子,再压入该节点的左孩子……(这样弹出时就是左孩子先弹出,右孩子再弹出,满足先序)

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
LinkedList<Integer> output = new LinkedList<Integer>();
if(root == null){
return output;
}

stack.add(root);
while(!stack.isEmpty()){
TreeNode node = stack.pollLast();
output.add(node.val);
if(node.right!=null){
stack.add(node.right);
}
if(node.left!=null){
stack.add(node.left);
}
}
return output;
}
}

中序遍历:栈不为空时开始循环,先压入左边界,然后弹出,再处理右子树,右子树也是这样的逻辑,先压入右子树的左边界,再处理右子树的右子树……

class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<>();
List<Integer> res = new ArrayList<>();
TreeNode curr = root;
while(curr != null || !stack.isEmpty()){
while(curr != null){
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
res.add(curr.val);
curr = curr.right;
}
return res;
}
}

中序拓展~中右左

后序遍历:中右左反过来,使用 help 栈;打印的时候不打印但是压入 help 栈,弹出即为后序。

class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
LinkedList<Integer> output = new LinkedList<Integer>();
if(root == null){
return output;
}

stack.add(root);
while(!stack.isEmpty()){
TreeNode node = stack.pollLast();
output.addFirst(node.val);
if(node.left != null){
stack.add(node.left);
}
if(node.right != null){
stack.add(node.right);
}
}
return output;
}
}

2. 如何直观的打印一颗二叉树

将打印结果顺时针旋转 90° 即为一棵二叉树,H 代表头节点,^ 代表该节点的父节点在左上方,v 代表该节点的父节点在左下方。

public class PrintBinaryTree {

public static void printTree(TreeNode head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}

public static void printInOrder(TreeNode head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.val + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}

public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}

public static void main(String[] args) {
TreeNode head = new TreeNode(1);
head.left = new TreeNode(-222222222);
head.right = new TreeNode(3);
head.left.left = new TreeNode(Integer.MIN_VALUE);
head.right.left = new TreeNode(55555555);
head.right.right = new TreeNode(66);
head.left.left.right = new TreeNode(777);
printTree(head);

printTree(head);

}

}

3. 在二叉树中找到一个节点的后继节点

【题目】 现在有一种新的二叉树节点类型如下:

public class Node { 
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int data) {
this.value = data;
}
}

该结构比普通二叉树节点结构多了一个指向父节点的parent指针。假设有一棵Node类型的节点组成的二叉树,树中每个节点的parent指针都正确地指向 自己的父节点,头节点的parent指向null。只给一个在二叉树中的某个节点 node,请实现返回node的后继节点的函数。在二叉树的中序遍历的序列中, node的下一个节点叫作node的后继节点。

public static TreeNode getSuccessorNode(TreeNode node) {
if (node == null) {
return node;
}
// node 如果有右孩子,后继节点为右孩子的最左节点
if (node.right != null) {
return getLeftMost(node.right);
} else {
// node 如果没有右孩子,往上找,如果为一个节点的左孩子时,这个节点为后继节点
TreeNode p = node.parent;
while (p != null) {
if (node == p.left) {
return p;
}
node = p;
p = p.parent;
}
}
// 如果找到根节点了 还没有这样的节点,那这个节点没有后继节点
return null;
}

public static TreeNode getLeftMost(TreeNode node) {
if (node == null) {
return null;
}
while (node.left != null) {
node = node.left;
}
return node;
}

4. 折纸问题

【题目】 请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时 折痕是凹下去的,即折痕突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。
给定一 个输入参数N,代表纸条都从下边向上方连续对折N次,请从上到下打印所有折痕的方向。

例如:N=1时,打印: down;N=2时,打印: down down up

5. 介绍二叉树的序列化和反序列化

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

序列化可以使用先序遍历、中序遍历或者层次遍历实现。需要注意一下两点:

  • 空节点要使用占位符:否则节点数据值一致且数量相同时无法还原结构
  • 节点与节点之间要使用分隔符:为了区分不同节点的数据值
public static String serialByPre(Node head) {
if (head == null) {
return "#!";
}
String res = head.value + "!";
res += serialByPre(head.left);
res += serialByPre(head.right);
return res;
}

public static Node reconByPreString(String preStr) {
String[] values = preStr.split("!");
Queue<String> queue = new LinkedList<>();
for (int i = 0; i != values.length; i++) {
queue.offer(values[i]);
}
return reconPreOrder(queue);
}

public static Node reconPreOrder(Queue<String> queue) {
String str = queue.poll();
if ("#".equals(str)) {
return null;
}
Node head = new Node(Integer.valueOf(str));
head.left = reconPreOrder(queue);
head.right = reconPreOrder(queue);
return head;
}

6. 判断一棵二叉树是否是平衡二叉树

平衡二叉树:对于一棵二叉树上的任意一个节点,左右子树的高度差不超过 1

public static class ReturnData {
public boolean isB;
public int h;

public ReturnData(boolean isB, int h) {
this.isB = isB;
this.h = h;
}
}

public static boolean isBalance2(Node head) {
return process(head).isB;
}

public static ReturnData process(Node head) {
if (head == null) {
return new ReturnData(true, 0);
}
ReturnData returnDataL = process(head.left);
if (!returnDataL.isB)
return new ReturnData(false, 0);
ReturnData returnDataR = process(head.right);
if (!returnDataR.isB)
return new ReturnData(false, 0);
if (Math.abs(returnDataL.h - returnDataR.h) > 1)
return new ReturnData(false, 0);
return new ReturnData(true, Math.max(returnDataL.h, returnDataR.h) + 1);
}

7. 判断一棵树是否是搜索二叉树、判断一棵树是否是完全二叉树

搜索二叉树:对于一棵二叉树上的任何一个节点,该节点的左孩子 < 该节点 < 该节点的右孩子。

通常来讲,搜索二叉树是不含有重复节点的,相同的节点值会压缩到一个节点中。

由定义可知,二叉树的中序遍历是升序的。

public static boolean isBST(Node head) {
if (head == null) {
return false;
}
int minNum = Integer.MIN_VALUE;
int cur;
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
}
head = stack.pop();
// 判断逻辑:不符合升序返回 false
cur = head.value;
if (cur < minNum) return false;
minNum = cur;
head = head.right;
}
return true;
}

public static boolean isCBT(Node head) {
if (head == null) {
return false;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
boolean leaf = false;
Node l;
Node r;
/**
* 1. 有右无左:false
* 2. 有左无右 无左无右:按层次遍历,后边全部为叶节点时为 true
* 3. 有左有右
*/
while (!queue.isEmpty()) {
head = queue.poll();
l = head.left;
r = head.right;
if ((leaf == true && (l != null || r != null))
|| l == null && r != null) return false;
if (l != null) {
queue.offer(l);
}
if (r != null) {
queue.offer(r);
} else {
leaf = true;
}
}
return true;
}

8. 已知一棵完全二叉树,求其节点的个数

要求:时间复杂度低于O(N),N为这棵树的节点个数

public static int nodeNum(Node head) {
if (head == null) {
return 0;
}
return bs(head, 1, mostLeftLevel(head, 1));
}

// 使用节点右子树的左边界做为判断依据
public static int bs(Node node, int level, int h) {
// 到底,以叶节点为头的完全二叉树节点个数为 1
if (level == h) {
return 1;
}
// 右子树左边界到底:左子树满、递归处理右子树
if (mostLeftLevel(node.right, level + 1) == h) {
// 注意运算符优先级,+ 优先级别大于 <<
return (1 << (h - level)) + bs(node.right, level + 1, h);
} else {
// 右子树左边界没到底:右子树满、递归处理左子树
return (1 << (h - level - 1)) + bs(node.left, level + 1, h);
}
}

public static int mostLeftLevel(Node node, int level) {
while (node != null) {
level++;
node = node.left;
}
return level - 1;
}
【AI编程】Vibe Coding 开发环境搭建与项目实战操作详解 Vibe Coding 开发环境搭建与项目实战操作详解 阅读详情

相关推荐

0009 用VisualStudio设计Max工具

这次分享个独家专利^)^:在Visual Studio中设计3dsMax脚本工具界面。 某次做原型设计时,需求改来改去,实在懒得搞GUI;虽然也尝试在Axure RP里画原型,但还是Visual Studio更顺手,也更容易测试一些交互,就直接在VS里做了。后来突发奇想,想实验一把能否直接用到Max里去,结果没想到成功了,效果还挺好。发现了新大陆,记录一下。   开始: 在VS里新建W...

whwst的专栏 770

左神系列|关于二叉树的总结

二叉树 \ 二叉树的前中后遍历 前序遍历 在二叉树中,前序遍历的顺序就是中左右,从根节点出发,先向自己的左子树遍历,在遍历的过程中,打印节点,知道左子树为空,在遍历右子树,重复上述步骤,最后打印节点的顺序就是根节点-左子节点-右子节点 它有两种实现方式: 第一种是递归方式,非常简单 遍历节点的时候先打印节点,然后再递归进入左子树,知道左子树为空,再进入右子树继续进行上述的流程,知道所有节点都被遍历完成 第二种是非递归方式,我们需要一个栈来完成,详细流程写在下图里 后续遍历 第一种方式就是

MarkusZhang的博客 466

Axure原型模板与元件库APP交互设计素材(附资料)

在Axure中,手机模型是展示APP或小程序界面效果的重要工具。通过导入手机模型元件,设计师可以更加直观地模拟真实设备的显示效果,从而更准确地评估设计的可行性和用户体验。Axure官方及第三方资源库中提供了多种品牌和型号的手机模型,如iPhone、Android等,设计师可以根据项目需求选择合适的模型进行使用。Axure作为一款强大的原型设计工具,为APP和小程序的设计与开发提供了丰富的界面组件元件库和交互设计素材。

招风的黑耳优快云 1981

左神算法整理笔记03

一个排序的重要性不仅仅局限于他的功能,思路的重要性 重要的排序算法:归并排序、快排、堆排 归并排序的思想:分治思想和master时间复杂度公式 快排的思路: 堆排的思想:

xlshi1996的博客 247

Win11专业版破解RDP限制:实现多用户远程桌面协同办公

本文详细介绍了如何在Windows 11专业版上破解RDP限制,实现多用户远程桌面协同办公。通过使用RDPWrap工具,用户可以绕过微软的授权限制,允许多个用户同时登录同一台电脑,提高硬件利用率和团队协作效率。文章包含详细的安装配置步骤、性能优化技巧及常见问题解决方案,适用于需要远程协作的办公场景。

weixin_33806300的博客 467

算法策略 | MACD跨周期短线交易策略开发(股指+商品双版)

量化策略开发,高质量社群,交易思路分享等相关内容

松鼠宽客的博客 2539

左神算法笔记之二叉树——二叉树中序先序后序遍历

一、二叉树递归和非递归方式实现先序、中序和后序遍历 public class PreInPosTraversal { public static class Node{ public int value; public Node left; public Node right; public Node(int data){ this.value = data; } //递归: //先序:头左右 public static void preOrderRecur(Node

weixin_43801264的博客 203

YOLOv11 Neck架构演进 - 从FPN/PAN到C2f/SPPF的融合策略实战剖析

本文深入剖析YOLOv11 Neck架构的演进历程,从FPN/PAN到C2f/SPPF的融合策略,详细解析了多尺度目标检测中的特征融合技术。通过实战案例展示了YOLOv11在无人机航拍等场景中的性能提升,特别是小目标检测AP值提升15%的显著效果,为计算机视觉开发者提供了宝贵的架构优化经验。

weixin_30500105的博客 434

左神视频day05——题目一:先中后序遍历,递归和非递归方式

实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式 import java.util.Stack; public class Code_01_PreInPosTraversal { public static class Node { public int value; public Node left; public Node ...

dl674756321的博客 332

海康/大华设备如何接入GB28181平台?最新2022版互联避坑指南

本文详细解析了海康/大华设备接入GB28181平台的最新2022版互联避坑指南,涵盖参数配置、实时视音频点播协议交互及典型故障排查。重点介绍了GB/T28181-2022标准下的设备编码规范、SIP服务器配置及媒体流保活机制,帮助工程团队高效解决设备离线和媒体流中断等问题。

weixin_30733003的博客 687

OTA 升级失败/回滚策略设计:打造安全可靠的双分区/断点续传/签名校验方案

双分区机制(A/B Partitioning)是OTA升级的“保险箱”。简单来说,设备存储分为两个分区:A分区(当前运行)和B分区(备用)。升级时,新固件写入B分区,A分区保持不变。如果升级成功,系统切换到B分区运行;如果失败,设备直接回滚到A分区,完全不受影响。这就像玩游戏存档:你打Boss前存了个档,万一挂了还能读档重来。双分区就是设备的“读档”机制,避免了变砖的尴尬。以Android设备为例,Google从Android 7.0开始强制引入A/B分区机制(Seamless Updates)。

大模型大数据攻城狮的专栏 1235

实现一个二叉树层级遍历_算法总结:左神class5—二叉树递归和非递归实现遍历(后序用一个栈彩蛋)...

二叉树类型的题目为常考题型1、能够结合队列、栈、链表、字符串等很多数据结构。2、需要掌握图的基本遍历方式,比如BFS和DFS。3、需要掌握递归函数的使用,并自己设计出递归过程。4、与实际工作结合紧密。面试中,二叉树节点类型仅包括:数据项、左孩子、右孩子。工程上的二叉树节点类型,往往多一条指向父节点的指针。一般默认面试中的二叉树节点结构不包含指向父节点的指针,除非特别说明。实现二叉树的先序...

weixin_40007668的博客 179

华为OD新系统机试真题 2026.5.10 - 美观的灯笼

华为OD新系统机试真题【美观的灯笼】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【美观的灯笼】

qq_45776114的博客 643

左神刷题

title: 左神刷题 date: 2018-09-21 17:32:47 categories: 算法刷题 tags: - 左神刷题 source: mac md update date: 2020-02-15 14:07:25 此文档包含左神书上题目(未完结,只做了部分)以及所涉及的leetcode题目,尽量都留存了最优解,部分简单的题目没有进行总结。 一、题目总览 编号...

Pop_Rain的博客 1427

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

左神基础算法笔记-一

1. 认识时间复杂度常数时间的操作:一个操作如果和数据量没有关系,每次都是固定的时间内完成的操作,叫做常数操作。 时间复杂度为一个算法流程中,常数操作数量的指标。常用O(读作big O)来表示。具体来说,在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分记为f(N),那么时间复杂度为O(f(N))。 评价一个算法流程的好坏,先看时间...

一盏小灯下 580

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

左神说:从面试出发讲解算法,边学习边面试(附左神讲解面试题)

在程序员界,说起Java,相信很多人知道马士兵,说起算法,我想很少有人会不知道左神,今天,左神就来了,带着offer走来了 从面试出发,讲解树的相关知识,视频+内容,先看视频后看文档,他不香吗? 左神说:从面试学算法 想要更多完整视频,私信“资料”获取,接下来就是重头戏呀,关于树的算法结构,代码呈上 .树 树:n(n>=0)个结点的有限集。 特点: - ...

Java架构师联盟 489

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

左神基础班-堆排序

#include<iostream> using namespace std; void heapsort(int arr[], int length); void heapinsert(int arr[], int length, int index); void heapify(int arr[], int index, int heapsize); void swap(int...

木剑温华 的 博客 469

左神的算法课笔记整理

简介:本文包含了 递归行为时间复杂度、快速排序的空间复杂度、堆排序、排序算法稳定性、工程中的综合排序算法、有关排序小知识 递归行为 递归行为时间复杂度 快速排序的空间复杂度 O(logN) ←原因是储存断点,二分再释放的过程,有多少个二分点,就需要多少的存储空间 堆排序 堆:完全二叉树 大根堆:任何一个子树的最大值都是这个子树的头部 插入操作:按照从左到右...

红尘倥偬的博客 2061

左神基础班-猫狗队列

#include<queue> #include<iostream> using namespace std; class Pet{ private: int type; public: Pet(){ } Pet(int type){ this->type = type; } int getType(){ return type; } v...

木剑温华 的 博客 308

左神基础班-切金条

#include<iostream> #include<queue> using namespace std; template<class T> int getLength(T& arr); int main(){ priority_queue<int,vector<int>,greater<int> &g...

木剑温华 的 博客 275

我的算法笔记 | 我决定摆烂了

本文是记录系统学习算法的一个过程记录。也是围绕我的计划 “80天刷题100道” 的一个总结记录。为什么要立这个Flag 呢,说白了还是觉得计算机这个行业已经卷到了一定的程度,而且从各个方面看到的信息,现在面试问算法已经是一个门槛。不希望自己因为算法而受到特别大的限制。另一方面也觉得算法无非也就这些东西,虽然它需要一定的时间,但是掌握了内核,应该也是一件一劳永逸的事情(当然还是需要复习的)。至少可以应对80% 的常见题目。 所以决定把功夫用在平时,全力准备一段时间。为了防止自己半途而废,给自己立了一个flag

博学之,审问之,慎思之,明辨之,笃行之 586

左神把困扰我多年的数据结构与算法讲透了,真真“算法第一人”

今年的面试都比较严格,特点是"要求高、薪资低"。也经常听见他们说某某大厂考了个手写算法,结果当场挂了。身为程序员的我们,再这样行业形势严峻、竞争压力大的情况下,只有不断提升自身能力,以确保在行业内能有个立足之地。《数据结构与算法》在我学生时代就是一门让我望而止步的课程。听着名字就感觉很晦涩难懂、需要大量的数学知识做铺垫。相信很多人也都和我一样,上学的时候学的一知半解,到了工作以后也很少用到就不了了之了。但是它却成为了你面试、寻找好的平台的障碍。

老男孩的架构路 1653

左神基础算法笔记-五

1. 认识哈希函数和哈希表哈希函数 哈希函数有很多种实现方式,md5,sha1。相似输入经过哈希函数后天差地别。 标准哈希函数输入域是无穷的,返回值是有范围的。 same input same out different input maybe same out(哈希碰撞) 离散性:输入域中的所有值均匀分布在返回范围上。(返回范围模后也均匀分布)(离散性越好的哈...

一盏小灯下 276

左神基础算法笔记-六

1. 图的表达、存储和生成方式图分为有向图和无向图,无向图可以用有向图来表示。 邻接表 上图用邻接表表示如下: 1:2 2:3,4 3:4 4:null 如果上图为无向图,则邻接表表示如下: 1:2 2:1,3,4 3:2,4 4:2,3 邻接矩阵 上图用邻接矩阵表示如下: 1:(2,7),(3,5) 2:(3,2) 3:null 图中点的存...

一盏小灯下 341

左神bilibili算法笔记-基础提升

左神算法系列笔记之算法提升

m0_50946672的博客 465

左神基础算法笔记-七

1. 前缀树(trieTree/prefixTree) 上图中的前缀树由“abc””abd””bcd””bkc”四个字符串组成,可以在前缀树的节点中封装数据项来增强前缀树的功能。 public static class TrieNode { public int path; public int end; public TrieNode[] nexts; ...

一盏小灯下 380
上一篇: 来北京一个月
下一篇: 左神基础算法笔记-五
铮诚
博客等级 码龄6年 6粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值