当前位置: 首页 > news >正文

每日算法2024/08/12

题目一:144. 二叉树的前序遍历❤

题目思路

看注释

题解代码

// 前序遍历·递归·LC144_二叉树的前序遍历
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<Integer>();preorder(root, result); // 前序遍历return result;}public void preorder(TreeNode root, List<Integer> result) {if (root == null) {return;}result.add(root.val);preorder(root.left, result);        // 左preorder(root.right, result);        // 右}
}
// 前序遍历迭代方式一
// 前序遍历顺序:中-左-右,入栈顺序:中-右-左
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();if (root == null){return result;}Stack<TreeNode> stack = new Stack<>();stack.push(root);while (!stack.isEmpty()){TreeNode node = stack.pop();  // 中result.add(node.val);if (node.right != null){stack.push(node.right); // 右(空节点不入栈)}if (node.left != null){stack.push(node.left); // 左(空节点不入栈)}}return result;}
}
// 前序遍历迭代方式二
class Solution {public static void preOrder(TreeNode root) {List<Integer> result = new ArrayList<>();//定义一个变量,存放当前节点TreeNode curr = root;//定义一个栈数据结构,用来存放遍历过程中的节点LinkedList<TreeNode> stack = new LinkedList<>();//当前孩子不为空或者栈中不为空,则循环while (curr != null || !stack.isEmpty()) {if (curr != null) {//如果当前节点不为空,打印result.add(curr.val);//打印后将该节点放入栈中stack.push(curr);//将curr指向当前节点的左孩子curr = curr.left;} else {//如果当前节点为空,则从栈中弹出节点TreeNode pop = stack.pop();//将curr指向弹出节点的右孩子(此时当前节点的所有左孩子和当前节点以及全部打印)curr = pop.right;}}}
}

题目二:94. 二叉树的中序遍历❤

题目思路

如上

题解代码

// 中序遍历·递归·LC94_二叉树的中序遍历
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();inorder(root, res);return res;}void inorder(TreeNode root, List<Integer> list) {if (root == null) {return;}inorder(root.left, list);list.add(root.val);             // 注意这一句inorder(root.right, list);}
}
    /*** 中序遍历——迭代*/
public static void inOrder(TreeNode root) {List<Integer> inOrder = new LinkedList<>();//先定义一个变量存放当前节点TreeNode curr = root;//定义一个栈数据结构,用来存放遍历过程中的节点LinkedList<TreeNode> stack = new LinkedList<>();//当左孩子不为空或者栈中不为空,则循环while (curr != null || !stack.isEmpty()) {if (curr != null) {//如果当前节点不为空,将其放入栈中stack.push(curr);//将curr指向当前节点的左孩子curr = curr.left;} else {//如果当前节点为空了,则从栈中弹出节点并输出(说明被弹栈节点左孩子为空)TreeNode pop = stack.pop();inOrder.add(pop.val);//将curr指向当前节点的右孩子curr = pop.right;}}
}


题目三:145. 二叉树的后序遍历❤

题目思路

如上

后序遍历的迭代代码需要注意如下:

  • 如果遍历到的节点为null时,不要急着将栈顶元素弹出,先通过peek方法获取到栈顶元素,判断栈顶元素的右孩子是否为null,或者右孩子是否已经被处理过(如何判断右孩子已经被处理?如果遍历到的节点的右孩子等于上一次被弹栈的元素,则说明右孩子已经被处理,因此后序遍历需要额外定义一个指针指向上一次被弹栈的节点),如果为null或者已经被处理,此时才弹出栈顶元素,如果没有,则需要先处理右孩子!!!

题解代码

// 后序遍历·递归·LC145_二叉树的后序遍历
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();postorder(root, res);return res;}void postorder(TreeNode root, List<Integer> list) {if (root == null) {return;}postorder(root.left, list);postorder(root.right, list);list.add(root.val);             // 注意这一句}
}
/*** 后序遍历*/
public static void postOrder(TreeNode root) {List<Integer> postOrder = new LinkedList<>();//先定义一个变量存放当前节点TreeNode curr = root;//定义一个栈数据结构,用来存放遍历过程中的节点LinkedList<TreeNode> stack = new LinkedList<>();//定义一个变量pop存放最近从栈中弹出的节点TreeNode pop = null;//当左孩子不为空或者栈中不为空,则循环while (curr != null || !stack.isEmpty()) {if (curr != null) {//如果当前节点不为空,将其放入栈中stack.push(curr);//将curr指向当前节点的左孩子curr = curr.left;} else {//后序遍历调用栈数据结构的peek方法,先操作栈顶元素,不急着弹出TreeNode peek = stack.peek();//如果栈顶节点的右孩子为空,或者与最近弹出栈的节点相同if (peek.right == null || peek.right == pop) {//则将栈顶元素弹出并打印pop = stack.pop();postOrder.add(pop.val);} else {//如果不是,则将curr指向栈顶元素的右孩子curr = peek.right;}}}
}

题目四:102. 二叉树的层序遍历❤

题目思路

看注释

题解代码

 
// 二叉树层序遍历-定义变量记录每层节点个数
public List<List<Integer>> levelOrder(TreeNode root) {// 存储结果List<List<Integer>> result = new ArrayList<>();// 如果根节点为空,则直接返回结果if (root == null) {return result;}// 创建一个队列Queue<TreeNode> queue = new LinkedList<>();// 将根节点放入队列queue.offer(root);// 记录每一层的节点个数int c1 = 1;//每一层节点个数// 当队列不为空时while (!queue.isEmpty()) {// 记录下一层节点个数int c2 = 0;//下一层节点个数// 创建一个存储每一层节点的列表List<Integer> lever = new ArrayList<>();// 遍历每一层节点for (int i = 0; i < c1; i++) {// 从队列中取出一个节点TreeNode node = queue.poll();// 将节点的值添加到列表中lever.add(node.val);// 如果该节点有左子节点,则将左子节点放入队列if (node.left != null) {queue.offer(node.left);c2++;}// 如果该节点有右子节点,则将右子节点放入队列if (node.right != null) {queue.offer(node.right);c2++;}}// 更新每一层节点个数c1 = c2;// 将每一层节点列表添加到结果中result.add(lever);}// 返回结果return result;
}
// 二叉树层序遍历-使用队列长度表示每层节点个数
public int maxDepth(TreeNode root) {if (root == null) {return 0;}//二叉树的层序遍历需要用到队列数据结构Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);//记录深度int depth = 0;while (!queue.isEmpty()) {//每一层节点个数<队列中元素个数记录的就是每一层节点的个数>int size = queue.size();//当前层有多少节点就循环多少次for (int i = 0; i < size; i++) {//就把多少节点从队列中弹出,并把它们的孩子加入队列TreeNode pollNode = queue.poll();if (pollNode.left != null) {queue.offer(pollNode.left);}if (pollNode.right != null) {queue.offer(pollNode.right);}}//每循环一层,层数 + 1depth++;}//当循环完所有节点,返回层数return depth;
}

题目五:107. 二叉树的层序遍历 II

题目思路

注释

题解代码

/*正常的层序遍历,只不过先将每一层遍历到的元素加入栈中最后将栈中的元素弹栈再加入结果集中,实现反转*/
public List<List<Integer>> levelOrderBottom(TreeNode root) {// 结果集List<List<Integer>> res = new ArrayList<>();// 栈Stack<List<Integer>> result = new Stack<>();if (root == null) {return res;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {List<Integer> level = new ArrayList<>();int size = queue.size();for (int i = 0; i < size; i++) {TreeNode polled = queue.poll();level.add(polled.val);if (polled.left != null) {queue.offer(polled.left);}if (polled.right != null) {queue.offer(polled.right);}}// 入栈result.push(level);}// 将栈中的元素弹栈加入结果集合while (!result.isEmpty()) {res.add(result.pop());}return res;
}
/*正常的层序遍历,在加入每一层的元素到结果集时,始终加入到结果集的链表头 res.add(0, level);*/
public List<List<Integer>> levelOrderBottom2(TreeNode root) {List<List<Integer>> res = new ArrayList<>();if (root == null) {return res;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {List<Integer> level = new ArrayList<>();// 使用队列长度表示每层节点的节点个数int size = queue.size();for (int i = 0; i < size; i++) {TreeNode polled = queue.poll();level.add(polled.val);if (polled.left != null) {queue.offer(polled.left);}if (polled.right != null) {queue.offer(polled.right);}}// 将每层的元素集合始终加入结果集的链表头res.add(0, level);}return res;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • windows和office微软官方免费激活教程
  • 选择江苏G口大带宽服务器租用的优势有哪些?
  • 简单了解一下 git cherry-pick
  • 2024专业音乐创作必备Guitar Pro8永久破解版激活码
  • 关于android中的各种尺寸与计算
  • javascript逻辑运算符
  • Ecovadis辅导是什么?哪些企业需要做Ecovadis辅导?
  • IO进程----标准IO
  • Redis-哨兵监控(sentinel)
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • 非对称加密算法-ECDHE
  • git cherry-pick
  • 第二十天的学习(2024.8.8)Vue拓展
  • serial靶场
  • QT学习从零开始,开发一个串口调试助手
  • CSS中外联样式表代表的含义
  • es6要点
  • Flex布局到底解决了什么问题
  • learning koa2.x
  • Vue.js源码(2):初探List Rendering
  • Vue实战(四)登录/注册页的实现
  • yii2中session跨域名的问题
  • 从tcpdump抓包看TCP/IP协议
  • 好的网址,关于.net 4.0 ,vs 2010
  • 数组的操作
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 一个JAVA程序员成长之路分享
  • (C++17) std算法之执行策略 execution
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (Git) gitignore基础使用
  • (MATLAB)第五章-矩阵运算
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (四)进入MySQL 【事务】
  • (译) 函数式 JS #1:简介
  • ***监测系统的构建(chkrootkit )
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET 回调、接口回调、 委托
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .Net语言中的StringBuilder:入门到精通
  • .NET值类型变量“活”在哪?
  • @Valid和@NotNull字段校验使用
  • [ 攻防演练演示篇 ] 利用通达OA 文件上传漏洞上传webshell获取主机权限
  • [ACM] hdu 1201 18岁生日
  • [ACP云计算]易混淆知识点(考题总结)
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [C# 网络编程系列]专题六:UDP编程
  • [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子
  • [flask]http请求//获取请求头信息+客户端信息