剑指Offer题目笔记31(图的搜索)

面试题105:

面试题105

解决方案:

​ 逐一扫描矩阵的每一个格子,如果遇到一个值为1的格子并且它不在已知的岛屿上,那么就到达了一个新的岛屿,于是搜索这个岛屿并且计算它的面积,在比较所有岛屿的面积之后就可以知道最大的岛屿的面积。

源代码(使用广度优先搜索):
class Solution {
    //主函数
    public int maxAreaOfIsland(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        //用于记录格子是否已经属于已知的岛屿上
        boolean[][] visited = new boolean[rows][cols];
        int maxArea = 0;
        for(int i = 0;i < rows;i++){
            for(int j = 0;j < cols;j++){
                if(grid[i][j] == 1 && !visited[i][j]){
                    int area = getArea(grid,visited,i,j);
                    maxArea = Math.max(area,maxArea);
                }
            }
        }

        return maxArea;
    }
    //广度优先搜索
    private int getArea(int[][] grid,boolean[][] visited,int i,int j){
        //创建队列。先将起始节点添加到队列中。接下来每步从队列中取出一个节点进行访问。
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{i,j});
        visited[i][j] = true;
        
		//四个方向,上、下、左、右。
        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
        int area = 0;
        //对于这个题目而言,每访问一个节点,岛屿的面积增加1。接下来从上、下、左、右这4个方向判断相邻的节点是不是还有没有到达过的值为1的节点,如果有,就将其添加到队列中。重复这个过程,直到队列的长度为0。
        while(!queue.isEmpty()){
            int[] pos = queue.remove();
            area++;

            for(int[] dir:dirs){
                int r = pos[0] + dir[0];
                int c = pos[1] + dir[1];
                if(r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] == 1 && !visited[r][c]){
                    queue.add(new int[]{r,c});
                    visited[r][c] = true;
                }
            }
        }

        return area;
    }
}
源代码(使用深度优先搜索):
class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        boolean[][] visited = new boolean[rows][cols];
        int maxArea = 0;
        for(int i = 0;i < rows;i++){
            for(int j = 0;j < cols;j++){
                if(grid[i][j] == 1 && !visited[i][j]){
                    int area = getArea(grid,visited,i,j);
                    maxArea = Math.max(area,maxArea);
                }
            }
        }

        return maxArea;
    }

    //深度优先搜索
    private int getArea(int[][] grid,boolean[][] visited,int i,int j){
        //将前面代码中的队列替换成栈,由于栈按照“后进先出”的顺序进行压栈、出栈操作,因此图搜索的顺序相应地变成深度优先搜索。
        Stack<int[]> stack = new Stack<>();
        stack.push(new int[]{i,j});
        visited[i][j] = true;

        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
        int area = 0;
        while(!stack.isEmpty()){
            int[] pos = stack.pop();
            area++;

            for(int[] dir:dirs){
                int r = pos[0] + dir[0];
                int c = pos[1] + dir[1];
                if(r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] == 1 && !visited[r][c]){
                    stack.push(new int[]{r,c});
                    visited[r][c] = true;
                }
            }
        }

        return area;
    }
}
源代码(使用递归):
class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        boolean[][] visited = new boolean[rows][cols];
        int maxArea = 0;
        for(int i = 0;i < rows;i++){
            for(int j = 0;j < cols;j++){
                if(grid[i][j] == 1 && !visited[i][j]){
                    int area = getArea(grid,visited,i,j);
                    maxArea = Math.max(area,maxArea);
                }
            }
        }

        return maxArea;
    }

    private int getArea(int[][] grid,boolean[][] visited,int i,int j){
        visited[i][j] = true;
        int area = 1;
        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};

        for(int[] dir:dirs){
            int r = i + dir[0];
            int c = j + dir[1];
            if(r >= 0 && r < grid.length && c >= 0 && c < grid[0].length && grid[r][c] == 1 && !visited[r][c]){
                area += getArea(grid,visited,r,c);
            }
        }

        return area;
    }
}

面试题106:

面试题106

解决方案:

​ 二分图的节点可以分成两种不同的类型,任意一条边的两个节点分别属于两种不同的类型。可以为图中的所有节点着色,两种不同类型的节点分别涂上不同的颜色。如果任意一条边的两个节点都能被涂上不同的颜色,那么整个图就是一个二分图。

源代码(使用广度优先搜索):
class Solution {
    public boolean isBipartite(int[][] graph) {
        int size = graph.length;
        int[] colors = new int[size];
        Arrays.fill(colors,-1);
        for(int i = 0;i < size;i++){
            if(colors[i] == -1){
                if(!setColor(graph,colors,i,0)){
                    return false;
                }
            }
        }

        return true;
    }
	//给节点着色
    private boolean setColor(int[][] graph,int[] colors,int i,int color){
        Queue<Integer> queue = new LinkedList<>();
        queue.add(i);
        colors[i] = color;
        while(!queue.isEmpty()){
            int v = queue.remove();
            for(int neighbor:graph[v]){
                if(colors[neighbor] >= 0){
                    //如果相邻节点颜色相同,则违背了二分图要求,因此返回false
                    if(colors[neighbor] == colors[v]){
                        return false;
                    }
                }else{
                    queue.add(neighbor);
                    colors[neighbor] = 1 - colors[v];
                }
            }
        }

        return true;
    }
}
源代码(使用深度优先搜索):
class Solution {
    public boolean isBipartite(int[][] graph) {
        int size = graph.length;
        int[] colors = new int[size];
        Arrays.fill(colors,-1);
        for(int i = 0;i < size;i++){
            if(colors[i] == -1){
                if(!setColor(graph,colors,i,0)){
                    return false;
                }
            }
        }

        return true;
    }

    private boolean setColor(int[][] graph,int[] colors,int i,int color){
        //如果该节点在此之前已经着色,并且它的颜色不是color,那么意味着不能按照二分图的规则对图中的节点进行着色,直接返回false。
        if(colors[i] >= 0){
            return colors[i] == color;
        }
		//如果此时节点i还没有着色,则将它的颜色设为color,然后给与它相邻的节点涂上颜色1-color。
        colors[i] = color;
        for(int neighbor:graph[i]){
            if(!setColor(graph,colors,neighbor,1-color)){
                return false;
            }
        }

        return true;
    }
}

面试题107:

面试题107

解决方案:

​ 根据题目的要求,上、下、左、右相邻的两个格子的距离为1。可以将图看成一个无权图,图中两个节点的距离是连通它们的路径经过的边的数目。

源代码:
class Solution {
    public int[][] updateMatrix(int[][] mat) {
        int rows = mat.length;
        int cols = mat[0].length;
        //定义矩阵D
        int[][] result = new int[rows][cols];
        Queue<int[]> queue = new LinkedList<>();
        for(int i = 0;i < rows;i++){
            for(int j = 0;j < cols;j++){
                if(mat[i][j] == 0){
                    queue.add(new int[]{i,j});
                    result[i][j] = 0;
                }else{
                    result[i][j] = Integer.MAX_VALUE;
                }
            }
        }
		//四个方向,上、下、左、右。
        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
        while(!queue.isEmpty()){
            int[] pos = queue.remove();
            int dist = result[pos[0]][pos[1]];
            for(int[] dir:dirs){
                int r = pos[0] + dir[0];
                int c = pos[1] + dir[1];
                if(r >= 0 && r < rows && c >= 0 && c < cols){
                    //值为1,并且与0的距离大于1时,才需要改变。
                    if(result[r][c] > dist + 1){
                        result[r][c] = dist+1;
                        queue.add(new int[]{r,c});
                    }
                }
            }
        }

        return result;
    }
}

面试题108:

面试题108

解决方案:

​ 这个题目要求计算最短演变序列的长度,即求图中两个节点的最短距离。表示单词演变的图也是一个无权图,按照题目的要求,图中两个节点的距离是连通两个节点的路径经过的节点的数目。

源代码(单向广度优先搜索):
class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        //创建两个队列,交替使用queue1和queue2这两个队列由近及远地从起始节点开始搜索所有节点。
        Queue<String> queue1 = new LinkedList<>();
        Queue<String> queue2 = new LinkedList<>();
        Set<String> notvisited = new HashSet<>(wordList);
		
        //因为beginWord与endWord不相同,因此改变长度至少为1.
        int length = 1;
        queue1.add(beginWord);
        while(!queue1.isEmpty()){
            String word = queue1.remove();
            if(word.equals(endWord)){
                return length;
            }
			//改变一个字符的word的全部情况
            List<String> neighbors = getNeighbors(word);
            for(String neighbor:neighbors){
                //如果单词列表存在该改变一个字符的情况,则添加到queue2中
                if(notvisited.contains(neighbor)){
                    queue2.add(neighbor);
                    notvisited.remove(neighbor);
                }
            }
			//因为队列queue2全是queue1的中word改变一个字符的情况,故length增加1,queue1遍历完切换到queue2
            if(queue1.isEmpty()){
                length++;
                queue1 = queue2;
                queue2 = new LinkedList<>();
            }   
        }

        return 0;
    }
	//改变字符串word的每一个字符,添加到链表中并返回
    private List<String> getNeighbors(String word){
        List<String> neighbors = new LinkedList<>();
        char[] chs = word.toCharArray();
        for(int i = 0;i < chs.length;i++){
            char old = chs[i];

            for(char ch = 'a';ch <= 'z';ch++){
                if(old != ch){
                    chs[i] = ch;
                    neighbors.add(new String(chs));
                }
            }

            chs[i] = old;
        }

        return neighbors;
    }
}
源代码(双向广度优先搜索):
class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        //set1和set2分别存放两个方向上当前需要访问的节点,set3用来存放与当前访问的节点相邻的节点。
        Set<String> notVisited = new HashSet<>(wordList);
        if(!notVisited.contains(endWord)){
            return 0;
        }
        
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();
        int length = 2;
        set1.add(beginWord);
        set2.add(endWord);
        notVisited.remove(endWord);
        while(!set1.isEmpty() && !set2.isEmpty()){
            //每次while循环都是从需要访问的节点数目少的方向搜索,这样做是为了缩小搜索的空间。
            if(set2.size() < set1.size()){
                Set<String> temp = set1;
                set1 = set2;
                set2 = temp;
            }

            Set<String> set3 = new HashSet<>();
            for(String word:set1){
                List<String> neighbors = getNeighbors(word);
                for(String neighbor:neighbors){
                    if(set2.contains(neighbor)){
                        return length;
                    }

                    if(notVisited.contains(neighbor)){
                        set3.add(neighbor);
                        notVisited.remove(neighbor);
                    }
                }
            }

            length++;
            set1 = set3;
        }

        return 0;
    }

    private List<String> getNeighbors(String word){
        List<String> neighbors = new LinkedList<>();
        char[] chs = word.toCharArray();
        for(int i = 0;i < chs.length;i++){
            char old = chs[i];

            for(char ch = 'a';ch <= 'z';ch++){
                if(old != ch){
                    chs[i] = ch;
                    neighbors.add(new String(chs));
                }
            }

            chs[i] = old;
        }

        return neighbors;
    }
}

面试题109:

面试题109

解决方案:
  1. 密码锁4个转轮上的数字定义了密码锁的状态,转动密码锁的转轮可以改变密码锁的状态。一般而言,如果一个问题是关于某事物状态的改变,那么可以考虑把问题转换成图搜索的问题。事物的每个状态是图中的一个节点,如果一个状态能够转变到另一个状态,那么这两个状态对应的节点之间有一条边相连。
  2. 对于这个问题而言,密码锁的每个状态都对应着图中的一个节点,如状态"0000"是一个节点,"0001"是另一个节点。如果转动某个转轮一次可以让密码锁从一个状态转移到另一个状态,那么这两个状态之间有一条边相连。
源代码:
class Solution {
    public int openLock(String[] deadends, String target) {
        //存储死锁情况
        Set<String> dead = new HashSet<>(Arrays.asList(deadends));
        Set<String> visied = new HashSet<>();
        String init = "0000";
        if(dead.contains(init) || dead.contains(target)){
            return -1;
        }

        Queue<String> queue1 = new LinkedList<>();
        Queue<String> queue2 = new LinkedList<>();
        int steps = 0;
        queue1.offer(init);
        visied.add(init);
        while(!queue1.isEmpty()){
            String cur = queue1.remove();
            if(cur.equals(target)){
                return steps;
            }

            List<String> nexts = getNeighbors(cur);
            for(String next:nexts){
                if(!dead.contains(next) && !visied.contains(next)){
                    queue2.add(next);
                    visied.add(next);
                }
            }

            if(queue1.isEmpty()){
                steps++;
                queue1 = queue2;
                queue2 = new LinkedList();
            }
        }
        return -1;
    }
	//得到转动一次的所有情况
    private List<String> getNeighbors(String cur){
        List<String> nexts = new LinkedList<>();
        for(int i = 0;i < cur.length();i++){
            char ch = cur.charAt(i);

            char newCh = ch == '0'?'9':(char)(ch-1);
            StringBuilder builder = new StringBuilder(cur);
            builder.setCharAt(i,newCh);
            nexts.add(builder.toString());

            newCh = ch == '9'?'0':(char)(ch + 1);
            builder.setCharAt(i,newCh);
            nexts.add(builder.toString());
        }

        return nexts;
    }
}

面试题110:

面试题110

解决方案:

​ 使用深度优先搜索,通常用递归实现。从节点0出发开始搜索。每当搜索到节点i时,先将该节点添加到路径中去。如果该节点正好是节点n-1,那么就找到了一条从节点0到节点n-1的路径。如果不是,则从graph[i]找到每个相邻的节点并用同样的方法进行搜索。当从节点i出发能够抵达的所有节点都搜索完毕之后,将回到前一个节点搜索其他与之相邻的节点。

源代码:
class Solution {
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(0,graph,path,result);
        return result;
    }
	//soure用于标记位于节点的位置
    private void dfs(int soure,int[][] graph,List<Integer> path,List<List<Integer>> result){
        path.add(soure);
        if(soure == graph.length-1){
            result.add(new ArrayList<>(path));
        }else{
            for(int next:graph[soure]){
                dfs(next,graph,path,result);
            }
        }

        path.remove(path.size() - 1);
    }
}

面试题111:

面试题111

解决方案:

​ 这个问题是关于两个变量之间的除法,因此可以将变量看作图中的节点。如果存在两个变量的除法等式,那么这两个变量对应的节点之间有一条边相连。一个除法等式除了被除数和除数,还有商。被除数和除数都对应图中的节点,商是两个变量的除法的结果,表达的是变量之间的关系,因此商应该是边的属性。可以给图中的每条边定义一个权重,为两个变量的除法的商。

源代码:
class Solution {
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {		
        Map<String,Map<String,Double>> graph = getGraph(equations,values);
        double[] results = new double[queries.size()];
        for(int i = 0;i < queries.size();i++){
            String from = queries.get(i).get(0);
            String to = queries.get(i).get(1);
            if(!graph.containsKey(from) || !graph.containsKey(to)){
                results[i] = -1;
            }else{
                Set<String> visited = new HashSet<>();
                results[i] = dfs(graph,from,to,visited);
            }
        }

        return results;
    }
	//记录两个变量的权重关系到map中
    private Map<String,Map<String,Double>> getGraph(List<List<String>> equations,double[] values){
        Map<String,Map<String,Double>> graph = new HashMap<>();
        for(int i = 0;i < equations.size();i++){
            String var1 = equations.get(i).get(0);
            String var2 = equations.get(i).get(1);
            
            graph.putIfAbsent(var1,new HashMap<>());
            graph.get(var1).put(var2,values[i]);

            graph.putIfAbsent(var2,new HashMap<>());
            graph.get(var2).put(var1,1.0/values[i]);
        }

        return graph;
    }
	//计算字符串from和字符串to的商
    private double dfs(Map<String,Map<String,Double>> graph,String from,String to,Set<String> visited){
        if(from.equals(to)){
            return 1.0;
        }

        visited.add(from);
        for(Map.Entry<String,Double> entry:graph.get(from).entrySet()){
            String next = entry.getKey();
            if(!visited.contains(next)){
                double nextValue = dfs(graph,next,to,visited);
                if(nextValue > 0){
                    return entry.getValue() * nextValue;
                }
            }
        }

        visited.remove(from);
        return -1.0;
    }
}

面试题112:

面试题112

解决方案:

​ 使用深度优先搜索找出从矩阵的每个数字出发的最长递增路径的长度。

源代码:
class Solution {
    public int longestIncreasingPath(int[][] matrix) {
        int[][] lengths = new int[matrix.length][matrix[0].length];
        int result = 1;
        for(int i = 0;i < matrix.length;i++){
            for(int j = 0;j < matrix[0].length;j++){
                int incrementNum = dfs(matrix,lengths,i,j);

                result = Math.max(result,incrementNum);
            }
        }

        return result;
    }

    private int dfs(int[][] matrix,int[][] lengths,int i,int j){
        if(lengths[i][j] != 0){
            return lengths[i][j];
        }

        int rows = matrix.length;
        int cols = matrix[0].length;
        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
        int length = 1;
        for(int[] dir:dirs){
            int r = i + dir[0];
            int c = j + dir[1];
            if(r >= 0 && r < rows && c >= 0 && c < cols && matrix[r][c] > matrix[i][j]){
                int path = dfs(matrix,lengths,r,c);
                length = Math.max(path+1,length);
            }
        }

        lengths[i][j] = length;
        return length;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高标准化及可扩展的产品能力,助力声通科技运营效率不断提升

高标准化及可扩展的产品能力对企业发展具有重要意义&#xff0c;有助于企业提高运营效率、增强市场竞争力&#xff0c;并推动企业实现规模化发展。上海声通信息科技股份有限公司&#xff08;下文称&#xff1a;声通科技或公司&#xff09;作为我国领先的企业级全栈交互式人工智…

C语言练习:变种水仙花数

今天让我们来看看变种的水仙花吧&#xff0c;话不多说&#xff0c;直入主题。 题目描述 变种水仙花数- Lily Number: 把任意的数字&#xff0c;从中间拆分成两个数字&#xff0c;比如1461可 以拆分成(1和461)&#xff0c;(14和61)&#xff0c;(146和1),如果所有拆分后的乘积之和…

Activity——绘制第一张流程图bpmn

文章目录 前言流程符号事件Event活动 Activity网关 GateWay流向 Flow 使用idea绘制第一张流程图设置流程图各节点属性流程图转换图片 问题原因与问题解决汇总问题一&#xff1a;流程乱码问题二&#xff1a;其他idea主题无左侧 Bpmn Editor 设置框问题三&#xff1a;idea右键xml…

DataGrip数据库管理工具安装使用

DataGrip数据库管理工具安装使用 DataGrip介绍 DataGrip是jetbrains旗下的一款数据库管理工具&#xff0c;相信做过java开发的同学都知道&#xff0c;idea就是这家公司发明的。 DataGrip 是JetBrains公司开发的数据库管理客户端工具&#xff08;操作数据库的IDE&#xff0c;…

imx6ull官方源码linux内核移植

1.尝试官方源码 在正点原子给的资料里找到NXP官方原版linux源码&#xff0c;路径为&#xff1a; 1、例程源码->4、 NXP 官方 原版 Uboot和 Linux->linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。复制并解压。 修改顶层Makefile 编译一下 make -j16 出现以下错误 修改 就…

react17 + antd4 如何实现Card组件与左侧内容对齐并撑满高度

在使用antd进行页面布局时&#xff0c;经常会遇到需要将内容区域进行左右分栏&#xff0c;并在右侧区域内放置一个或多个Card组件的情况。然而&#xff0c;有时我们会发现右侧的Card组件并不能与左侧的栏目对齐&#xff0c;尤其是当左侧栏目高度动态变化时。本文将介绍如何使用…

基于SSM的游戏攻略管理系统

游戏攻略管理系统的构建与实现 一、系统概述二、系统架构与技术选型三、系统功能模块四、系统特点五、总结与展望 随着网络游戏的普及和发展&#xff0c;游戏攻略成为玩家们提升游戏技能、了解游戏机制的重要途径。为了更好地满足玩家需求&#xff0c;提高游戏攻略的管理效率和…

centos7离线安装postgresql13

**一.**安装存储库RPM yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm二.使用yumdownloader下载安装包 mkdir pg_yum cd pg_yum yumdownloader --resolve postgresql13-server**三.**上传rpm包到安…

Python的pytest框架(1)--基本概念、入门

按基础到进阶的顺序&#xff0c;学习Python的pytest框架&#xff0c;本篇文章先讲一讲pytest的基本概念、入门使用规则。 目录 一、pytest基础知识 1、安装 2、pytest框架主要做了什么工作 二、pytest的规则约定、运行方式以及参数详解 1、编写测试用例 模块&#xff08…

GitHub repository - commits - branches - releases - contributors

GitHub repository - commits - branches - releases - contributors 1. commits2. branches3. releases4. contributorsReferences 1. commits 在这里可以查看当前分支的提交历史。左侧的数字表示提交数。 2. branches 可以查看仓库的分支列表。左侧的数字表示当前拥有的分…

asyncio异步编程

参考视频&#xff1a;02 协程_哔哩哔哩_bilibili 1.协程&#xff1a;&#xff08;不是计算机中真实存在的&#xff0c;人为创造出的概念&#xff09;&#xff0c;也可称为微线程。 本质是用一个线程在一段代码中来会切换游走的线程&#xff0c;是一种用户态内的上下文切换技术…

【数据结构与算法】最大公约数与最小公倍数

最大公因数&#xff08;英语&#xff1a;highest common factor&#xff0c;hcf&#xff09;也称最大公约数&#xff08;英语&#xff1a;greatest common divisor&#xff0c;gcd&#xff09;是数学词汇&#xff0c;指能够整除多个非零整数的最大正整数。例如8和12的最大公因数…

Linux系统部署可视化数据多维表格APITable并实现无公网IP远程协同办公

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-G5XdKx1vxX0o0PES {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

说说你对集合的理解?常见的操作有哪些?

一、是什么 集合&#xff08;Set&#xff09;&#xff0c;指具有某种特定性质的事物的总体&#xff0c;里面的每一项内容称作元素 在数学中&#xff0c;我们经常会遇到集合的概念&#xff1a; 有限集合&#xff1a;例如一个班集所有的同学构成的集合无限集合&#xff1a;例如…

上网方法介绍

注册 https://www.cordcloud.biz/user 注册后先充值&#xff0c;充值后还要购买套餐&#xff0c; 充值之后&#xff0c;就可以看到流量了&#xff0c;然后复制订阅地址&#xff0c;到客户端去自动下载 URL拷贝到这个地方&#xff0c;然后点击下载

latex论文写作学习

首先无论是什么文章&#xff0c;最基础的格式都是这个&#xff1a; 如何修改字体呢&#xff1f;&#xff1a; 这样一来就可以在写完之后统一改掉了&#xff0c;用来做标记 最后记得\par 插图&#xff1a; 命令后面的中括号一般就是option

ESP32S3学习笔记(0)—— Vscode IDF环境搭建及OpenOCD调试介绍

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动/单片机/RTOS的实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff…

男生穿什么裤子最百搭?适合男生穿的裤子品牌测评分享

每个伙伴们想必经常都会选择一些裤子&#xff0c;但现在市面上的裤子品牌也实在太多了&#xff0c;好不容易选到了几件好看的裤子&#xff0c;结果质量却很不好。主要就是因为现在有太多商家为了利润而使用一些舒适性、质量差的面料&#xff0c;那么今天就给大家分享一些质量上…

实战小项目 | ESP32-S3和ESP32-C3通过ESP-Mesh-Lite组网 温湿度传感器案例

传统Wi-Fi网络所有终端设备都需要直接与路由器相连&#xff0c;这使得Wi-Fi的覆盖区域受到路由器位置的限制&#xff0c;可接入终端设备的数量也受到路由器容量的限制。而乐鑫ESP-Mesh-Lite Wi-Fi组网方案&#xff0c;所有终端设备都可以与相邻设备连接&#xff0c;摆脱了对路由…

酒店水电能源计量管理系统

酒店水电能源计量管理系统是一种针对酒店行业设计的能源管理系统&#xff0c;旨在实现对水电能源的计量、监测和管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.多元化计量&#xff1a;该系统能够对酒店内的水、电能源进行多元化计量&#xff0c;…