LeetCode 441, 57, 79

news2024/9/22 13:23:52

目录

  • 441. 排列硬币
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 57. 插入区间
    • 题目链接
    • 标签
    • 思路
      • 两个区间的情况
      • 对每个区间的处理
      • 最终的处理
    • 代码
  • 79. 单词搜索
    • 题目链接
    • 标签
    • 原理
      • 思路
      • 代码
    • 优化
      • 思路
      • 代码

441. 排列硬币

题目链接

441. 排列硬币

标签

数学 二分查找

思路

由于本题所返回的 答案在区间 [1, n],并且 答案越大,所需要的硬币越大 (有序),所以采用 二分枚举答案 的思想。

由于要找 最多 的完整阶梯的总行数,所以使用二分法的 前驱 实现,因为一个数的前驱是 最后一个小于该数 的数。不了解二分法的后继与前驱的可以看这篇文章:算法——二分法。

代码

class Solution {
    public int arrangeCoins(int n) {
        // 二分枚举答案
        long left = 1, right = n; // 答案的区间为 [1, n]
        while (left < right) { // 使用二分法的 前驱 实现
            long mid = left + (right - left + 1 >> 1); // 猜想答案
            if (n < sum(mid)) { // 如果 猜想的答案 太大了
                right = mid - 1; // 则 缩小 猜想的答案
            } else { // 如果 猜想的答案 太小了 或 猜对了
                left = mid; // 则 扩大 猜想的答案
            }
        }
        return (int) left;
    }
    // 获取 layer 层阶梯 需要的硬币总数
    private long sum(long layer) {
        return layer * (layer + 1) / 2;
    }
}

57. 插入区间

题目链接

57. 插入区间

标签

数组

思路

由于题目中提示 可以不原地修改 intervals,所以可以创建一个 List<int[]> 类型的变量 list,将所有的区间都添加到 list 中,同时 合并重叠的区间,在最后返回 list 转换为 int[][] 的形式。本题的重点在于如何合并区间。

两个区间的情况

两个区间的情况

如上图,区间 curr 和 区间 new 之间共有 3 中情况:

  • 如果 interval[1] < left,则 currnew 左边。
  • 如果 right < interval[0],则 currnew 右边。
  • 如果以上两种情况都不满足,并且有 interval[0] < right,则 currnew 有交集。注意:此情况包含 c u r r ⊂ n e w curr \subset new currnew n e w ⊂ c u r r new \subset curr newcurr c u r r = n e w curr = new curr=new 这三种特殊情况。

对每个区间的处理

令 新区间newInterval 的左、右端点分别为 left, right,从区间的集合 intervals 中取出单个区间 interval,其左、右端点分别为 interval[0], interval[1],则对于 新区间 new 和 当前选取的区间 curr,根据不同情况可分为以下三种处理方式:

  • currnew 左边时,直接将 当前区间curr 加入到 list 中。
  • currnew 右边时,将 新区间new 加入到 list 中,并把 当前区间curr 当作 新区间new
  • currnew 有交集时,将 当前区间curr 合并到 新区间new 中,此时新区间的端点值需要被更新,左端点更新为 较小 的左端点,右端点更新为 较大 的右端点。

最终的处理

这种处理方式会导致 最后的新区间 没有被加入到 list 中,以下,针对 倒数第二个区间curr 和 新区间new 做如下讨论,证明 最后的新区间 没有被加入到 list 中:

  • currnew 左边时,只将 倒数第二个区间curr 加入到 list 中,而没有将 new 加入到 list 中。
  • currnew 右边时,只将 新区间new 加入到 list 中,而没有将被看作 新区间new 的倒数第二个区间curr 加入到 list 中。
  • currnew 有交集时,只是更新了 新区间new 的左、右端点,而没有将其加入到 list 中。

综上所述,最后的新区间 确实没有被加入到 list 中,所以在返回结果之前得先把 最后的新区间 加入到 list 中。

代码

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        if (intervals.length == 0){ // 如果 intervals 为空
            return new int[][]{newInterval}; // 则将 newInterval 作为唯一的区间返回
        }

        int left = newInterval[0], right = newInterval[1]; // left, right 分别为 合并后的新区间的 左端点 和 右端点
        List<int[]> list = new ArrayList<>(intervals.length);
        for (int[] interval : intervals) {
            if (right < interval[0]) { // 如果 当前区间的左端点 大于 新区间的右端点,即 curr 在 new 右边
                // 注意这里不能直接写 list.add(newInterval)
                // 因为新区间可能经过合并,此时左、右端点可能就与原来不同了
                list.add(new int[]{left, right}); // 则将新区间加入 list

                // 将 当前区间 当作 新区间
                left = interval[0];
                right = interval[1];
            } else if (interval[1] < left) { // 如果 当前区间的右端点 小于 新区间的左端点,即 curr 在 new 左边
                list.add(interval); // 将当前区间加入 list
            } else { // 当前区间与新区间有交集,合并它们
                left = Math.min(left, interval[0]); // 取 左端点 的较小值
                right = Math.max(right, interval[1]); // 取 右端点 的较大值
            }
        }

        // 将 最后的新区间 加入 list
        list.add(new int[]{left, right});

        return list.toArray(new int[list.size()][]); // 将 List<int[]> 转为 int[][]
    }
}

79. 单词搜索

题目链接

79. 单词搜索

标签

数组 字符串 回溯 矩阵

原理

思路

本题可以使用 深度优先搜索 的思想:以矩阵中每个元素作为 word 的起始字符,搜索合适的字符串,如果能找到合适的字符串,则返回 true。步骤如下:

  • 如果要遍历一个字符,那么它得满足以下 3 个条件,如果任意一个不成立,则返回 false;否则继续匹配。
    1. 当前字符在矩阵 board
    2. 当前字符没有被遍历过
    3. 当前字符与本轮搜索要匹配的 word 中的字符相等
  • 如果当前字符匹配的是 word 中的最后一个字符,则可以返回 true,代表找到合适的字符串了;否则继续匹配。
  • 标记当前字符已被遍历过了。
  • 分别向上下左右搜索下一个字符,如果其中有一个方向匹配成功,则直接返回 false
  • 取消遍历过当前字符的标记,清除本次搜索对下一次搜索的影响。
  • 如果能到这一步,则说明没有匹配成功,返回 false

由于 同一个单元格内的字母不允许被重复使用,所以 在搜索时得记录每个元素是否遍历过,可以使用 boolean[][] 来记录 board 中的每个元素是否遍历过。

代码

class Solution {
    public boolean exist(char[][] board, String word) {
        // 对成员变量进行赋值
        ROW = board.length;
        COL = board[0].length;
        this.vis = new boolean[ROW][COL];
        this.board = board;
        this.word = word.toCharArray();

        // 以矩阵中每个元素作为 word 的起始字符,搜索合适的字符串
        for (int r = 0; r < ROW; r++) {
            for (int c = 0; c < COL; c++) {
                if (dfs(r, c, 0)) { // 如果能找到合适的字符串
                    return true; // 则返回 true
                }
            }
        }
        
        return false; // 找不到合适的字符串,返回 false
    }
    // (r, c) 指向 board 中的字符,curr 指向 word 中的字符
    private boolean dfs(int r, int c, int curr) {
        if (!(r >= 0 && r < ROW && c >= 0 && c < COL) // 如果 (r, c) 指向的元素在矩阵外
                || vis[r][c] // 或 (r, c) 指向的元素已被遍历过
                || board[r][c] != word[curr]) { // 或 字符匹配失败
            return false; // 则返回 false
        } else if (curr == word.length - 1) { // 当前字符匹配成功,如果当前字符匹配的是最后一个字符
            return true; // 则返回 true
        }

        vis[r][c] = true; // 标记遍历过 (r, c) 指向的元素
        for (int k = 0; k < 4; k++) { // 枚举四个方向
            int kr = r + dir[k][0], kc = c + dir[k][1]; // (kr, kc) 指向待遍历的元素
            if (dfs(kr, kc, curr + 1)) { // 如果后面的字符都匹配成功了
                return true; // 则返回 true
            }
        }
        vis[r][c] = false; // 取消 遍历过 (r, c) 指向元素的标记

        return false; // 匹配失败,返回 false
    }
    private int ROW; // 矩阵的行数
    private int COL; // 矩阵的列数
    private char[][] board; // 使用成员变量保存 board
    private char[] word; // 使用成员变量保存 word
    private boolean[][] vis; // 判断某个元素是否遍历过
    private int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; // 方向数组,分别为 向右、向下、向左、向上
}

优化

思路

上面的代码运行起来比较慢,主要有两个优化点:

  1. 不使用方向数组 dir,而是一个一个地将四个方向写出来。
  2. 标记是否遍历过某个元素时可以不使用 boolean[][] vis,而是将 board 的字符变为一个与英文字母不相关的字符——'\0',然后再将其还原为原本的字母,这样在判断时就将 vis[r][c] 合并到 匹配字符的操作 board[r][c] != word[curr] 中,这样做可以减少时间的浪费。

代码

class Solution {
    public boolean exist(char[][] board, String word) {
        // 对成员变量进行赋值
        ROW = board.length;
        COL = board[0].length;
        this.board = board;
        this.word = word.toCharArray();

        // 以矩阵中每个元素作为 word 的起始字符,搜索合适的字符串
        for (int r = 0; r < ROW; r++) {
            for (int c = 0; c < COL; c++) {
                if (dfs(r, c, 0)) { // 如果能找到合适的字符串
                    return true; // 则返回 true
                }
            }
        }
        
        return false; // 找不到合适的字符串,返回 false
    }
    // (r, c) 指向 board 中的字符,curr 指向 word 中的字符
    private boolean dfs(int r, int c, int curr) {
        if (!(r >= 0 && r < ROW && c >= 0 && c < COL) // 如果 (r, c) 指向的元素在矩阵外=
                || board[r][c] != word[curr]) { // 或 字符匹配失败
            return false; // 则返回 false
        } else if (curr == word.length - 1) { // 当前字符匹配成功,如果当前字符匹配的是最后一个字符
            return true; // 则返回 true
        }

        board[r][c] = '\0'; // 标记遍历过 (r, c) 指向的元素
        boolean res = dfs(r, c + 1, curr + 1) // 向右
                        || dfs(r + 1, c, curr + 1) // 向下
                        || dfs(r - 1, c, curr + 1) // 向左
                        || dfs(r, c - 1, curr + 1); // 向上 分别向四个方向搜索能否找到合适的字符串
        board[r][c] = word[curr]; // 取消 遍历过 (r, c) 指向元素的标记

        return res; // 返回 分别向四个方向搜索能否找到合适的字符串
    }
    private int ROW; // 矩阵的行数
    private int COL; // 矩阵的列数
    private char[][] board; // 使用成员变量保存 board
    private char[] word; // 使用成员变量保存 word
}

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

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

相关文章

通过 PPPOE 将 linux 服务器作为本地局域网 IPv4 外网网关

将 linux 服务器作为本地外网网关&#xff0c;方便利用 Linux 生态中的各种网络工具&#xff0c;对流量进行自定义、精细化管理… 环境说明 拨号主机&#xff1a;CentOS 7.9, Linux Kernel 5.4.257 拨号软件: rp-pppoe-3.11-7.el7.x86_64初始化 1、升级系统到新的稳定内核&a…

半年GMV狂飙166亿!酒水赛道正在崛起自播之路

从2022年开始&#xff0c;酒水以“兴趣”为核心的直播电商迎来爆发式增长。以抖音电商为例&#xff0c;2022年下半年整体销售额破百亿&#xff0c;环比增幅超100%&#xff0c;2023年全年更是破300亿大关&#xff01;兴趣电商成为酒行业的第二增长曲线。 今年上半年&#xff0c;…

机器学习第四十七周周报 CF-LT

文章目录 week47 CF-LT摘要Abstract1. 题目2. Abstract3. 网络结构3.1 CEEMDAN&#xff08;完全自适应噪声集合经验模态分解&#xff09;3.2 CF-LT模型结构3.3 SHAP 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程 5. 结论6.代码复现小结参考文献 week47 CF-LT 摘要 本周…

可视耳勺是不是智商税?五款好用挖耳勺推荐!

随着人们追求健康生活方式的需求日益增长&#xff0c;可视耳勺这一产品逐渐走入了人们的视野&#xff0c;并受到了广泛的青睐。 然而&#xff0c;市场上可视耳勺品牌和种类繁多&#xff0c;部分产品存在清晰度不高、亮度较暗等问题&#xff0c;在使用过程很容易存在损坏耳道的风…

负载箱如何帮助维持电气系统的最佳性能

负载箱在维持电气系统最佳性能方面发挥着至关重要的作用&#xff0c;以下是负载箱如何帮助维持电气系统最佳性能的详细分析&#xff1a; 一、保护电气设备 负载箱能够在电气系统中产生恒定的负载&#xff0c;使电气设备在正常工作状态下运行。这避免了因负载波动过大而导致的…

数据库管理1

数据库管理 数据库运维。 sql语句 数据库用来增删改查的语句 备份 数据库的数据进行备份 主从复制&#xff0c;读写分离&#xff0c;高可用。 数据库的概念和相关的语法和规范&#xff1a; 数据库&#xff1a;组织&#xff0c;存储&#xff0c;管理数据的仓库。 数据库的管理系…

FreeRTOS_定时器

定时器概述 定时器运行过程 定时器就像一个闹钟&#xff0c;它有超时时间、函数、是否为周期性这三个部分。 超时时间&#xff1a;什么时候到时间&#xff0c;就像闹钟响起函数&#xff1a;闹钟响起&#xff0c;要干什么是否为周期性&#xff1a;这个闹钟只响一次&#xff0…

杭州高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

杭州高校大学智能制造数字孪生技术作为智能制造的重要支撑&#xff0c;通过构建虚拟世界的镜像&#xff0c;实现对物理世界的实时监控、预测和优化。杭州高校大学智能制造实验室数字孪生可视化系统平台建设项目&#xff0c;旨在通过引入先进的数字孪生技术&#xff0c;构建一个…

刚刚,Claude国内可直连!

刚刚&#xff0c;Claude国内可直连&#xff01; 大家好&#xff01;我是科技博主Maynor。今天我们要分享一个激动人心的消息&#xff1a;知名AI助手Claude现在可以在国内直接访问了&#xff01; 这对于科技爱好者、学生、研究人员和各行各业的专业人士来说都是一个重大利好。…

进嵌入式公司当学徒没工资去不去啊?

在开始前分享一些嵌入式资料需要的同学评论888即可拿走 是我根据网友给的问题精心整理的 嵌入式是做技术岗位。技术不到位&#xff0c;没有人会要你。技术都没有&#xff0c;还要你的&#xff0c;一定是骗子。记住这句话就行了。 世上哪有那么好的事情。能免费让你学到真正有…

线性代数|机器学习-P24加速梯度下降(动量法)

文章目录 1. 概述2. 引入3. 动量法梯度下降 1. 概述 我们之前学的最速梯度下降[线搜索方法] 公式如下&#xff1a; x k 1 x k − s k ∇ f ( x k ) \begin{equation} x_{k1}x_k-s_k\nabla f(x_k) \end{equation} xk1​xk​−sk​∇f(xk​)​​ 但对于这种方法来说&#xff…

debian固定ip

debian固定ip 前言 安装好的Debian系统后&#xff0c;为了确保每次登陆的ip不变&#xff0c;需要固定 方法 命令如下 ip addr | grep inet因为有有线网和无线网 2 种连接方式&#xff0c;因此需要区别。 其中 enp 的是有线&#xff0c;wlp 的是无线 查看网关 IP 命令如下 …

蓝牙BLE广播

这里只讨论蓝牙BLE广播 这部分可以看蓝牙标准Core Specification V5.3的卷3 Host part C。当然广播参数那一块和“控制器”层有关&#xff0c;只需要了解广播参数的含义和设置方法就行&#xff0c;控制器的细节不太容易理解。 主要目标 广播参数&#xff08;广播间隔、TX 功…

MySQL学习记录 —— 이십일 MySQL服务器配置与管理(1)

文章目录 1、配置和默认值2、系统变量和选项1、介绍2、常用选项3、使用系统变量 3、常用服务器配置4、查看状态变量5、MySQL数据目录 mysql的服务端就是mysqld&#xff0c;d就是daemon&#xff0c;守护进程的意思。 配置文件中[mysqld]部分时服务器支持的启动选项。服务器的部…

flv文件转换成mp4?这四种转换方法肯定可以帮到你!

flv文件转换成mp4&#xff1f;FLV格式曾一度以其独特的地位&#xff0c;为视频传输领域注入了新的活力&#xff0c;然而&#xff0c;随着时间的流逝和技术的进步&#xff0c;这种格式也出现了很多问题&#xff0c;其最大的困扰在于兼容性的局限&#xff0c;尽管在某些特定场合下…

客户管理必备:快速学会群发微信信息新技能!

当我们用微信向客户传递祝福、福利等重要信息时&#xff0c;随着微信好友人数不断增加&#xff0c;在微信里挑选好友发送信息&#xff0c;既费时又费力&#xff0c;还容易因个人疏忽导致重要客户遗漏。 为了有效地解决上述问题&#xff0c;企业可以借助微信管理系统中群发管理功…

卸载wps office的几种方法收录

​ 第一种方法: 1.打开【任务管理器】&#xff0c;找到相关程序&#xff0c;点击【结束任务】。任务管理器可以通过左下角搜索找到。 2.点击【开始】&#xff0d;【设置】&#xff0d;【应用】&#xff0d;下拉找到WPS应用&#xff0c;右键卸载&#xff0c;不保留软件配置 …

不会用电子商务知识库?五项基本方法让你业务增长100%

电子商务公司正努力增加利润并减少支出。该行业正在不断发展&#xff0c;预计到 2040 年&#xff0c;95% 的所有购买行为都将通过电子商务进行。话虽如此&#xff0c;竞争依然激烈——95% 的客户表示&#xff0c;客户服务是决定是否与公司开展业务的关键因素。在购买过程中更快…

tomcat搭建

目录 1 Tomcat简介 2 Tomcat安装 2.1 安装JDK 2.2 安装Tomcat 3 Tomcat目录结构 3.1 tomcat主目录介绍 3.2 Tomcat配置文件目录介绍 3.3 Tomcat web管理功能 1 Tomcat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个…

1985年-2020年中国历年私人汽车保有量统计报告

数据来源于国家统计局&#xff0c;为1985年到2020年中国每年私人汽车拥有量&#xff08;包括客车、货车和其他汽车&#xff09;。2020年&#xff0c;中国私人汽车拥有量为2.43亿辆。 数据统计单位为&#xff1a;万辆 数据说明&#xff1a; 私人汽车包括私人载客汽车和私人载…