解决最短路径问题

news/2024/9/21 16:36:34 标签: 算法, java, leetcode

文章目录

  • 1. 迷宫中离入口最近的出口(1926)
  • 2. 最小基因变化(433)
  • 3. 单词接龙(127)
  • 4. 为高尔夫比赛砍树(675)


1. 迷宫中离入口最近的出口(1926)

题目描述:
在这里插入图片描述
在这里插入图片描述

算法原理:
其实路径最短问题和前一篇博客说到的FloodFill问题我理解的最大区别就是,出队的时候前者需要一次性出完,也就是每次出队需要记录size然后要等size个元素出完队,后者则是一个一个出队。针对这一题逻辑上也是一样,元素出队要一层一层地去出,然后如果说当前出队的元素的上下左右其中一个元素坐标满足相应条件,并且没被遍历过不是墙,并且恰好来到了边缘那么就返回,如果入队的所有元素都出完了还没返回就说明在迷宫出不去了,此时返回-1,具体看代码。
代码如下:

java">class Solution {
    public int nearestExit(char[][] maze, int[] entrance) {
        int m = maze.length, n = maze[0].length;
        boolean[][] vis = new boolean[m][n];
        int ret = 0;
        int[] dx = {1, -1, 0, 0};
        int[] dy = {0, 0, 1, -1};
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{entrance[0], entrance[1]});
        vis[entrance[0]][entrance[1]]=true;
        while (!queue.isEmpty()) {
            ret++;
            int sz = queue.size();
            while (sz-- != 0) {
                int[] tmp = queue.poll();
                int a = tmp[0], b = tmp[1];
                for (int i = 0; i < 4; i++) {
                    int x = a + dx[i];
                    int y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && maze[x][y] == '.') {
                        queue.add(new int[]{x, y});
                        vis[x][y] = true;
                        if (x == 0 || x == m - 1 || y == 0 || y == n - 1) {
                            return ret;
                        }

                    }

                }
            }
        }
        return -1;
    }
}

题目链接

2. 最小基因变化(433)

题目描述:
在这里插入图片描述

算法原理:
题目要我们去将给定的start字符串去转化为end的字符串并且转化过程的字符串需要包含在bank数组之内并且改变的字符就只是ACGT,我们可以使用上题类似的思想将start放入一个队列,然后使用两层的循环,第一层去遍历字符串的位数,第二层去遍历ACGT,这两层循环就代表着去将start字符串的每一位都用ACGT的每一个字符轮流替换一下,如果变换出的新的字符串包含在bank中并且没有被访问过,那么就将其加入队列并且开始下一轮直至变换至end字符串。当然还有一种特殊情况就是bank当中不包含end,那么直接返回-1即可。
代码如下:

java">class Solution {
    public int minMutation(String startGene, String endGene, String[] bank) {
        Set<String> hash = new HashSet<>();
        Set<String> vis = new HashSet<>();
        char[] chs = { 'A', 'C', 'G', 'T' };
        for (String str : bank) {
            hash.add(str);
        }

        if (startGene.equals(endGene)) {
            return 0;
        }

        if (!hash.contains(endGene)) {
            return -1;
        }

        Queue<String> queue = new LinkedList<>();
        queue.add(startGene);
        vis.add(startGene);

        int ret = 0;

        while (!queue.isEmpty()) {
            ret++;
            int size = queue.size();
            while (size-- != 0) {
                String t = queue.poll();
                for (int i = 0; i < 8; i++) {
                    char[] temp = t.toCharArray();
                    for (int j = 0; j < 4; j++) {
                        temp[i] = chs[j];
                        String next = new String(temp);
                        if (!vis.contains(next) && hash.contains(next)) {
                            if (next.equals(endGene)) {
                                return ret;
                            }
                            queue.add(next);
                            vis.add(next);
                        }
                    }
                }
            }

        }
        return -1;
    }
}

题目链接

3. 单词接龙(127)

题目描述:
在这里插入图片描述

算法原理:
这一题和上一题的做法和思想类似,唯一的区别就是步数是上题步数加一。
代码如下:

java">class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> hash = new HashSet<String>();
        for (String str : wordList) {
            hash.add(str);
        }
        Set<String> vis = new HashSet<String>();
        Queue<String> q = new LinkedList<>();
        int ret = 1;
        q.add(beginWord);
        vis.add(beginWord);
        while (!q.isEmpty()) {
            int sz = q.size();
            ret++;
            while(sz--!=0) {
                String s=q.poll();
                for(int i=0;i<s.length();i++) {
                    char[] ss=s.toCharArray();
                    for(char ch='a';ch<='z';ch++) {
                        ss[i]=ch;
                        String temp=new String(ss);
                        if(hash.contains(temp)&&!vis.contains(temp)) {
                            if(temp.equals(endWord)) {
                                return ret;
                            }
                            q.add(temp);
                            vis.add(temp);
                        }
                    }
                }
            }
        }
        return 0;
    }
}

题目链接

4. 为高尔夫比赛砍树(675)

题目描述:
在这里插入图片描述

算法原理:
根据题意我们可以简化问题,将每个树在矩阵中的坐标管理在队列中,并且根据树的高度进行降序排序。然后从(0,0)出发将出队的第一队坐标作为终点来计算需要多少步,后续就是类似起点就换成上一次的终点,终点就换成下一次出队的坐标。将每段过程的步数加起来就是最终的结果。
代码如下:

java">class Solution {
    int m, n;

    public int cutOffTree(List<List<Integer>> forest) {
        m = forest.size();
        n = forest.get(0).size();
        List<int[]> trees = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (forest.get(i).get(j) > 1) {
                    trees.add(new int[] { i, j });
                }
            }
        }
        Collections.sort(trees, (a, b) -> {
            return forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]);
        });
        int ret = 0;
        int bx = 0, by = 0;
        for (int[] tree : trees) {
            int x = tree[0], y = tree[1];
            int step = bfs(forest, bx, by, x, y);
            if (step == -1) {
                return -1;
            }
            ret += step;
            bx = x;
            by = y;
        }
        return ret;
    }

    int[] dx = { 1, -1, 0, 0 };
    int[] dy = { 0, 0, 1, -1 };

    public int bfs(List<List<Integer>> forest, int bx, int by, int ex, int ey) {
        if (ex == bx && ey == by) {
            return 0;
        }
        int step = 0;
        Queue<int[]> q = new LinkedList<>();
        boolean[][] vis = new boolean[m][n];
        q.add(new int[] { bx, by });
        vis[bx][by] = true;
        while (!q.isEmpty()) {
            int sz = q.size();
            step++;
            while (sz-- != 0) {
                int[] temp = q.poll();
                int a = temp[0], b = temp[1];
                for (int i = 0; i < 4; i++) {
                    int x = a + dx[i], y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && forest.get(x).get(y) != 0) {
                        if (x == ex && y == ey) {
                            return step;
                        }
                        q.add(new int[] { x, y });
                        vis[x][y] = true;
                    }
                }
            }
        }
        return -1;
    }
}

题目链接


http://www.niftyadmin.cn/n/5669074.html

相关文章

技术美术百人计划 | 《4.5 DOF景深算法》笔记

1. 景深定义 景深&#xff08;Depth of Field&#xff0c;DOF&#xff09;&#xff0c;是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。镜头光圈、镜头焦距、及焦平面到拍摄物的距离是影响景深的重要因素。在聚焦完成后&#xff0c;焦点…

【2024】MySQL账户管理

当前MySQL版本为&#xff1a; mysql> select version(); ----------- | version() | ----------- | 8.4.2 | ----------- 1 row in set (0.01 sec)目录 创建普通用户为用户授权查看用户权限修改用户权限修改用户密码删除用户 创建普通用户 使用CREATE USER语句创建用户…

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】010 - 二号内核线程 kthreadd线程 工作流程分析

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】010 - 二号内核线程 kthreadd线程 工作流程分析 一、kthreadd 线程代码工作流程分析二、如何添加任务到 kthread_create_list 链表 中三、__kthread_create_on_node() 函数工作流程分析系列文章汇总:《鸿蒙OH-v5.0源码分析之 Uboo…

机器翻译之创建Seq2Seq的编码器、解码器

1.创建编码器、解码器的基类 1.1创建编码器的基类 from torch import nn#构建编码器的基类 class Encoder(nn.Module): #继承父类nn.Moduledef __init__(self, **kwargs): #**kwargs&#xff1a;不定常的关键字参数super().__init__(**kwargs)def forward(self, X, *args…

uniapp使用uview2上传图片功能

官网地址Upload 上传 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 前提&#xff0c;需要下载vuew2插件 <view class"upload"><view class"u-demo-block__content"><view class"u-page__upload-item"&…

锐尔15注册机 锐尔文档扫描影像处理系统15功能介绍

锐尔文档扫描影像处理系统是一款全中文操作界面的文件、档案扫描及影像优化处理软件&#xff0c;是目前国内档案数字化行业里专业且优秀的影像优化处理软件。 无论是从纸质文件制作高质量的影像文件&#xff0c;或是检查已经制作好的影像文件&#xff0c;锐尔文档扫描影像处理…

2024 “华为杯” 中国研究生数学建模竞赛(D题)深度剖析|大数据驱动的地理综合问题|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题&#xff01; CS团队倾注了大量时间和心血&#xff0c;深入挖掘解…

英语<数词>

1.基数 one two three 整数 1 2 3 小数 1.1 2.2 3.2 分数 分子用基数&#xff0c;分母用序数 例子 1/3 one third 分子>1 2/3 two thirds 百分数 2.序数 first second