LeetCode 441, 57, 79

目录

  • 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.mfbz.cn/a/797757.html

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

相关文章

Qt中https的使用,报错TLS initialization failed和不能打开ssl.lib问题解决

前言 在现代应用程序中&#xff0c;安全地传输数据变得越来越重要。Qt提供了一套完整的网络API来支持HTTP和HTTPS通信。然而&#xff0c;在实际开发过程中&#xff0c;开发者可能会遇到SSL相关的错误&#xff0c;例如“TLS initialization failed”&#xff0c;cantt open ssl…

春招冲刺百题计划|双指针

Java基础复习 Java数组的声明与初始化Java ArrayListJava HashMapJava String 类Java LinkedListJava Deque继承LinkedListJava SetJava 队列优先队列:第二题用到了Java数组划分Java数组转ArrayListString 转数字String 这一部分&#xff0c;代码随想录写得超级好&#xff01…

LabVIEW阀门运动PCT测试

开发了一套基于LabVIEW的阀门运动PCT&#xff08;Pressure-Composition-Temperature&#xff09;测试方法。该系统通过控制阀门运动&#xff0c;实现对氢气吸附和解吸过程的精确测量和控制。所用硬件包括NI cDAQ-9174数据采集模块、Omega PX309压力传感器、SMC ITV2030电动调节…

【java算法专场】滑动窗口(下)

目录 水果成篮 算法分析 算法步骤 示例 算法代码 找到字符串中所有字母异位词 算法分析 算法步骤 示例 算法代码 优化 算法代码 串联所有单词的子串 算法分析 算法步骤 示例 算法代码 最小覆盖子串 算法分析 算法步骤 示例 算法代码 算法分析 这道题其实…

Python数据分析案例52——基于SSA-LSTM的风速预测(麻雀优化)

案例背景 又要开始更新时间序列水论文的系列的方法了&#xff0c;前面基于各种不同神经网络层&#xff0c;还有注意力机制做了一些缝合模型。 其实论文里面用的多的可能是优化算法和模态分解&#xff0c;这两个我还没出专门的例子&#xff0c;这几天正好出一个优化算法的例子来…

go-高效处理应用程序数据

一、背景 大型的应用程序为了后期的排障、运营等&#xff0c;会将一些请求、日志、性能指标等数据保存到存储系统中。为了满足这些需求&#xff0c;我们需要进行数据采集&#xff0c;将数据高效的传输到存储系统 二、问题 采集服务仅仅针对某个需求开发&#xff0c;需要修改…

树莓派pico入坑笔记,esp01/01s使用

目录 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树莓派pico专栏 说明 关于at指令 WiFi的at指令 UDP的at指令 样例程序 调试助手端输入指令 sta端程序 效果 进阶使用 库函数说明 样例代码 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树…

TensorFlow系列:第四讲:MobileNetV2实战

一. 加载数据集 编写工具类&#xff0c;实现数据集的加载 import keras""" 加载数据集工具类 """class DatasetLoader:def __init__(self, path_url, image_size(224, 224), batch_size32, class_modecategorical):self.path_url path_urlself…

H5的Canvas如何画N叉树数据结构

大家好。我是猿码叔叔&#xff0c;一位有着 5 年Java工作经验的北漂&#xff0c;业余时间喜欢瞎捣鼓&#xff0c;学习一些新东西来丰富自己。看过上一篇 Java 方法调用关系的老铁们&#xff0c;也许遗留了不少疑问&#xff0c;这Java方法调用关系可视化页面就这&#xff1f;这方…

护网HW面试——redis利用方式即复现

参考&#xff1a;https://xz.aliyun.com/t/13071 面试中经常会问到ssrf的打法&#xff0c;讲到ssrf那么就会讲到配合打内网的redis&#xff0c;本篇就介绍redis的打法。 未授权 原理&#xff1a; Redis默认情况下&#xff0c;会绑定在0.0.0.0:6379&#xff0c;如果没有采用相关…

基于SpringBoot的校园志愿者管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;MyEclipse、Tomcat 系统展示 首页 个人中心 志愿者管理 活动信息…

黑马头条微服务学习day01-环境搭建、SpringCloud微服务(注册发现、网关)

文章目录 项目介绍环境搭建项目背景业务功能技术栈说明 nacos服务器环境准备nacos安装 初始工程搭建环境准备主体结构 app登录需求分析表结构分析手动加密微服务搭建接口定义功能实现登录功能实现 Swagger使用app端网关nginx配置 项目介绍 环境搭建 项目背景 业务功能 技术栈说…

数据结构(Java):树二叉树

目录 1、树型结构 1.1 树的概念 1.2 如何判断树与非树 1.3 树的相关概念 1.4 树的表示形式 1.4.1 孩子兄弟表示法 2、二叉树 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 二叉树的遍历 1、树型结构 1.1 树的概念 树型结构是一种非线…

MySQL复合查询(重点)

前面我们讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远不够。 基本查询回顾 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的J mysql> select * from emp where (sal>500 or jobMANAGER) and ename l…

数据湖仓一体(一) 编译hudi

目录 一、大数据组件版本信息 二、数据湖仓架构 三、数据湖仓组件部署规划 四、编译hudi 一、大数据组件版本信息 hudi-0.14.1zookeeper-3.5.7seatunnel-2.3.4kafka_2.12-3.5.2hadoop-3.3.5mysql-5.7.28apache-hive-3.1.3spark-3.3.1flink-1.17.2apache-dolphinscheduler-3.1.9…

[Vulnhub] Sedna BuilderEngine-CMS+Kernel权限提升

信息收集 IP AddressOpening Ports192.168.8.104TCP:22, 53, 80, 110, 111, 139, 143, 445, 993, 995, 8080, 55679 $ nmap -p- 192.168.8.104 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 …

C++20中的consteval说明符

在C20中&#xff0c;立即函数(immediate function)是指每次调用该函数都会直接或间接产生编译时常量表达式(constant expression)的函数。这些函数在其返回类型前使用consteval关键字进行声明。 立即函数是constexpr函数&#xff0c;具体情况取决于其要求。与constexpr相同&…

半小时获得一张ESG入门证书【详细中英文笔记一】

前些日子&#xff0c;有朋友转发了一则小红书的笔记给我&#xff0c; 标题是《半小时获CFI官方高颜值免费证书 ESG认证》。这对考证狂魔的我来说&#xff0c;必然不能错过啊&#xff0c;有免费的羊毛不薅白不薅。 ESG课程的 CFI 官方网址戳这里&#xff1a;CFI 于是信心满满的…

清华大学孙富春教授团队开发了多模态数字孪生环境,辅助机器人获得复杂的 3C 装配技能

中国是全球3C产品&#xff08;电脑、通信和消费电子&#xff09;的主要生产国&#xff0c;全球70%的3C产品产能集中在中国。3C智能制造装备的突破与产业化&#xff0c;对于提升我国制造产业的全球竞争力意义重大。 机器人在计算机、通信和消费电子 &#xff08;3C&#xff09; …