Java二阶知识点总结(四)常见算法的基本结构

一、二叉树的DFS(深度优先算法)

1、递归

  • 基本递归(以中序遍历为例)
	public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result=new ArrayList<>();order(root,result);return result;}public void order(TreeNode node,List<Integer> result){	//递归携带的参数看情况设置if(node==null){	//这里要写一个递归终止条件return;}//这里可插入其他业务逻辑order(node.left,result);    //进入左节点result.add(node.val);		//业务代码,此处为中序遍历例order(node.right,result);	//进入右节点//这里可插入其他业务逻辑}
  • 递归+前缀和+从下到上传递累加值(力扣437:路径总和)
	public int pathSum(TreeNode root, int targetSum) {Map<Long,Integer> prefix=new HashMap<Long,Integer>();prefix.put(0L,1);return dfs(root,prefix,0,targetSum);}public int dfs(TreeNode root,Map<Long,Integer> prefix,long sum,int targetSum){if(root==null){return 0;}int result=0;	//结果累加值sum+=root.val;	//当前值result=prefix.getOrDefault(sum-targetSum,0);	//若前缀和Map中存在计算总值-目标值对应的值,说明计算总值-这段前缀和=目标值prefix.put(sum,prefix.getOrDefault(sum,0)+1);	//存储前缀和result+=dfs(root.left,prefix,sum,targetSum);	//左递归result+=dfs(root.right,prefix,sum,targetSum);	//右递归prefix.put(sum,prefix.getOrDefault(sum,0)-1);	//从当前节点返回后,要把对应前缀和去掉return result;	//传递累加值}
  • 递归+分治(力扣105:从前序和中序遍历序列构造二叉树)
	int[] preorder;HashMap<Integer, Integer> dic = new HashMap<>();public TreeNode buildTree(int[] preorder, int[] inorder) {this.preorder = preorder;for(int i = 0; i < inorder.length; i++)dic.put(inorder[i], i);return dfs(0, 0, inorder.length - 1);}public TreeNode dfs(int curr,int left,int right){if(left>right){return null;}TreeNode node=new TreeNode(preorder[curr]);int i=dic.get(preorder[curr]);node.left=dfs(curr+1,left,i-1);node.right=dfs(curr+i-left+1,i+1,right);return node;}
  • 递归+标记(力扣236:二叉树的最近公共祖先)
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null||root==p||root==q){	//若相等,则将该节点标记并往上传return root;}TreeNode left=lowestCommonAncestor(root.left,p,q);	//左递归TreeNode right=lowestCommonAncestor(root.right,p,q);	//右递归//放在递归最后是因为要从下往上排查if(left==null&&right==null){	//若两边都没有找到目标节点,则返回的是nullreturn null;}if(left==null){		//如果只是一边没找到,说明另外一边找到了return right;}if(right==null){	//同理return left;}return root;	//如果左右两边都找到了,说明这就是最近的公共祖先,直接往上传}

2、迭代

  • 基本迭代(中序遍历例)
	public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<Integer>();Deque<TreeNode> stack = new LinkedList<TreeNode>();	//Stack类已过时,使用Deque代替栈while (root != null || !stack.isEmpty()) {	//while (root != null) {	//后进先出,从最右侧的节点开始stack.push(root);	//push入栈root = root.left;}//这里可插入其他业务逻辑root = stack.pop();		//pop出栈res.add(root.val);		//业务代码,此处为中序遍历例root = root.right;		//回溯时再进入右侧节点//这里可插入其他业务逻辑}return res;}

二、二叉树的BFS(广度优先算法、层序遍历)

  • 迭代
public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();if (root != null) {	//队列中加入初始节点queue.offer(root);}while (!queue.isEmpty()) {	//只要队列不为空就一直进行int n = queue.size();List<Integer> level = new ArrayList<>();for (int i = 0; i < n; i++) { 	//只循环当前层拥有的节点次数TreeNode node = queue.poll();level.add(node.val);if (node.left != null) {	//若不为空就把下一层的节点加入,并且排到后面queue.offer(node.left);}if (node.right != null) {	//左右各一次queue.offer(node.right);}}res.add(level);}return res;}

三、图论的DFS

  • 核心思想在于上下左右的操作,以及边界的判断
  • 例题:力扣200.岛屿数量
	int result=0;public int numIslands(char[][] grid) {int result=0;for(int i=0;i<grid.length;i++){for(int j=0;j<grid[0].length;j++){if(grid[i][j]=='1'){result++;dfs(grid,i,j);}}}return result;}public void dfs(char[][] grid, int r, int c) {// 判断 base caseif (!inArea(grid, r, c)) {return;}// 如果这个格子不是岛屿,直接返回if (grid[r][c] != '1') {return;}grid[r][c] = '0'; // 将格子标记为「已遍历过」// 访问上、下、左、右四个相邻结点dfs(grid, r - 1, c);dfs(grid, r + 1, c);dfs(grid, r, c - 1);dfs(grid, r, c + 1);}// 判断坐标 (r, c) 是否在网格中public boolean inArea(char[][] grid, int r, int c) {return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;}

四、二分查找

  • 核心思想在于两点,一是退出循环的条件是左小于右,二是每次都把范围缩小一半
  • 参考(力扣704.二分查找)
    public int search(int[] nums, int target) {int left=0,right=nums.length-1;while(left<=right){int mid=(right-left)/2+left;int num=nums[mid];if(num==target){return mid;}else if(num>target){right=mid-1;}else{left=mid+1;}}return -1;}

五、单调栈

  • 核心思想在于维护栈内保持单调,当栈顶元素小于或大于要放入的元素时,就持续弹出
 Stack<Integer> stack = new Stack<>();int[] nums = new int[]{9, 6, 4, 3, 1, 2, 6, 3};for (int num : nums) {//如果栈顶元素小于要放入的元素,就弹出。while (!stack.isEmpty() && stack.peek() < num) {	//核心步骤stack.pop();//后续业务}stack.push(num);}

六、回溯

  • 回溯的核心思想是当后续流程走完后,返回到原始状态
  • 如题:力扣46.全排列
	public void dfs(List<Integer> list,int n,int[] nums){if(n==nums.length){result.add(new ArrayList(list));return;}for(int i=0;i<nums.length;i++){if(flag[i]==0){list.add(nums[i]);	//满足条件后进行标记flag[i]=1;dfs(list,n+1,nums);	//递归到下一层flag[i]=0;			//返回到该层时,把原先的标记清除list.remove(list.size()-1);}}}

参考

  • 102.二叉树层序遍历
  • 94.二叉树的中序遍历
  • 236.二叉树的最近公共祖先
  • 200.岛屿数量
  • 【Java数据结构与算法】单调栈的运用思路及相关题解

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

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

相关文章

从零开始学HCIA之IPv6基础05

1、IPv6地址支持无状态自动配置方式&#xff0c;主机通过某种机制获取网络前缀信息&#xff0c;然后主机自己生成地址的接口标识部分。 2、路由器发现功能是IPv6地址自动配置功能的基础&#xff0c;主要通过两种消息实现。 &#xff08;1&#xff09; 路由器通告&#xff08;…

springboot247人事管理系统

人事管理系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;问卷信息因为其管理内容繁杂&#xff0c;管理数量繁多导…

webpack5基础--09_处理其他资源

处理其他资源 开发中可能还存在一些其他资源&#xff0c;如音视频等&#xff0c;我们也一起处理了 1. 配置 const path require("path");module.exports {entry: "./src/main.js",output: {path: path.resolve(__dirname, "dist"),filename…

Redis基本使用和基础知识整理

Redis是做什么的&#xff1f; Redis是一个开源&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列。Redis将数据储存在内存当中 内存的特点 易失性&#xff08;在断电之后数据就没有了&#xff09;进行读取数据等IO操作的速度要比…

C语言进阶—表达式求值

隐式类型转换&#xff1a; C 的整型算术运算总是至少以缺省(默认)整型类型的精度来进行的。 为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升。 #include <stdio.h>int main() {char c 1;printf(…

Springboot 的几种配置文件形式

方式一&#xff1a;多个yml文件 步骤1&#xff1a;创建多个配置文件 application.yml #主配置文件 application-dev.yml #开发环境的配置 application-prod.yml #生产环境的配置 application-test.yml #测试环境的配置步骤2&#xff1a;applicaiton.yml中指定配置 在a…

代码随想录day13(1)栈与队列:用栈实现队列(leetcode232)

题目要求&#xff1a;使用栈实现push、pop、empty、peek&#xff08;返回队列首部元素&#xff09;。 思路&#xff1a;本题思路比较容易&#xff0c;即用两个栈模拟即可&#xff0c;pop时只需要先判断stackout栈是否为空&#xff0c;如果不空直接弹出&#xff0c;如果空就将s…

JVM双亲委派模型

Java虚拟机的双亲委派模型是一种类加载机制&#xff0c;用于确保Java类在被加载时的安全性和一致性。该模型通过将类加载请求委派给父类加载器来保证类加载的顺序和一致性。这个模型主要由以下几个关键点组成&#xff1a; 双亲委派&#xff1a; 当Java虚拟机收到加载类的请求时…

restTemplate请求接口转发(包含普通get,post请求和下载)

此代码包含普通get&#xff0c;post请求和下载&#xff0c;代码如下&#xff1a; Configuration public class RestTemplateConfig {Beanpublic RestTemplate restTemplate() {return new RestTemplate();}}Data public class CustomButtonRequestDto {ApiModelProperty(value…

PTA天梯 L2-001 紧急救援

作为一个城市的应急救援队伍的负责人&#xff0c;你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候&#xff0c;你的任务是带领你的…

组合逻辑电路(一)(加法器)

目录 组合逻辑电路的特点及功能描述 采用SSI的组合逻辑电路的分析与设计 采用SSI的组合逻辑电路的分析 采用SII的组合逻辑电路的设计 例 例 例 常用的MSI组合逻辑电路 半加器 全加器 加法器 串行进位加法器 例 例 超前进位加法器 组合逻辑电路的特点及功能描述 小规模集成…

原生微信小程序电影购票+后台管理系统[含文档]

简介 正文获取联系方式&#xff01;❤❤❤关于JAVA/小程序/安卓/PHP/Python/C#/ASP.NET/大数据/爬虫/数据可视化都可推荐选题和提供专业的指导和支持。 【毕设源码推荐项目】基于原生微信小程序电影购票系统 适用于计算机类毕业设计&#xff0c;本系统功能完整&#xff0c;适合…

TypeScript新手指南:何时使用.ts,何时转向.tsx?

在TypeScript中&#xff0c;.ts和.tsx文件扩展名代表两种不同的文件类型&#xff1a; .ts&#xff1a;这是一个标准的TypeScript文件&#xff0c;它可以包含TypeScript代码&#xff0c;该代码最终会被编译成JavaScript。.ts文件通常不包含JSX代码&#xff0c;JSX是一种JavaScri…

基础小白快速入门并行计算------>我们为什么要学习并行计算

什么是并行计算&#xff1f; 随着计算机的不断发展&#xff0c;我们处理的数据不断变多&#xff0c;需要更大得到处理能力、我们希望计算机有着更大更强壮的计算能力&#xff0c;由于cpu的运行能力有限&#xff0c;我们便想到了将多个cpu进行串联计算问题&#xff0c;这也就是我…

AtCoder Beginner Contest 343(A,B,C,D,E,F)

比赛链接 CE是暴力&#xff0c;D是数据结构题&#xff0c;F是线段树。这场的E比较有意思&#xff0c;其他的感觉有点水。 A - Wrong Answer 题意&#xff1a; 给你两个数 A , B A,B A,B ( 0 ≤ A , B ≤ 9 ) (0\le A,B\le 9) (0≤A,B≤9)&#xff0c;返回一个个位数&#…

Java类加载流程?

Java类加载过程是指将.class文件中的字节码数据加载到内存中&#xff0c;并生成对应的Class对象的过程。Java类加载器&#xff08;ClassLoader&#xff09;负责执行这个任务。Java类加载过程主要包括以下几个步骤&#xff1a; 加载&#xff08;Loading&#xff09;&#xff1a;…

Codeforces Round 883 (Div. 3)(集训队加训1)

A.如果钉子与地面距离大于绳子的长度就必须剪 #include<bits/stdc.h> #define eps 1e-5 #define INF 1e9 using namespace std; typedef long long ll; const int N 2e6 9; int a[N],b[N],cl[N]; void Lan(){int n;cin>>n;for(int i1;i<n;i){cin>>a[i]…

如何提高项目成功率?分享20 种项目管理工具、技术和软件

本文将分享20种项目管理常用的工具、技术和软件&#xff0c;比如项目管理软件 PingCode、Worktile、Redmine、Jira、SAP、PrimaveraSystems等&#xff1b;项目计划阶段工具和技术WBS、甘特图、PERT图、风险评估矩阵等等。 项目管理是确保项目成功交付的关键&#xff0c;它涉及到…

Java学习笔记009——局部内部类(需配合接口使用)

局部内部类&#xff08;Local Inner Classes&#xff09;在Java中是一种非常有用的特性&#xff0c;尽管它们的使用场景相对较少。局部内部类定义在一个方法、构造器或代码块中&#xff0c;而不是在类的顶层。这样的设计有几个主要的意义&#xff1a; 1. 代码组织&#xff1a;…

【产品文档分类及撰写路径】

一、产品文档的分类 产品文档根据所处阶段和面相对象的差异大致可以分为三类&#xff1a; 商业需求文档 (BRD)&#xff1a;商业需求文档是面向公司高层和项目组&#xff0c;目的是为了获得资金、资源支持。市场需求文档 (MRD)&#xff1a;市场需求文档是面向运营和市场销售人员…