怒刷LeetCode的第26天(Java版)

目录

第一题

题目来源

题目内容

解决方法

方法一:动态规划

第二题

题目来源

题目内容

解决方法

方法一:有限状态自动机

方法二:正则表达式

第三题

题目来源

题目内容

解决方法

方法一:从最后一位向前遍历

方法二:数学运算


第一题

题目来源

64. 最小路径和 - 力扣(LeetCode)

题目内容

解决方法

方法一:动态规划

可以使用动态规划来解决这个问题。

  1. 首先创建一个与网格大小相同的二维数组dp,用于存储从起点到每个位置的最小路径和。
  2. 然后初始化dp[0][0] = grid[0][0],表示起点的最小路径和为起点的值。
  3. 接下来进行动态规划的遍历,遍历顺序可从起点开始按行或按列遍历。对于每个位置dp[i][j],其最小路径和为grid[i][j]加上它左边或上边位置的最小路径和的较小值。

复杂度分析:

时间复杂度:

  • 遍历网格中的每个元素,所以需要进行两层嵌套循环,总共遍历次数为m * n,其中m为网格的行数,n为网格的列数。
  • 在每次循环中,执行常数时间的操作,将上方和左方的最小路径和与当前位置的值相加,然后取最小值。
  • 因此,整体的时间复杂度为O(m * n)。

空间复杂度:

  • 创建了一个与网格大小相同的二维数组dp,用于存储从起点到每个位置的最小路径和。因此需要额外的空间来存储这些最小路径和。
  • dp数组的大小为m * n,与原始网格的大小相同。
  • 所以,空间复杂度为O(m * n)。

综上所述,该算法的时间复杂度为O(m * n),空间复杂度为O(m * n)。

LeetCode运行结果:

第二题

题目来源

65. 有效数字 - 力扣(LeetCode)

题目内容

解决方法

方法一:有限状态自动机

可以使用有限状态自动机(DFA)来解决该问题。我们需要设计合适的状态集合以及状态转移规则。其中,状态包括以下几种:

起始空格状态:在这个状态下,前面的空格已经被忽略。 符号位状态:在这个状态下,可能出现 + 或 -。 整数状态:在这个状态下,输入了数字 0-9。 小数点状态:在这个状态下,已经输入了小数点。 小数状态:在这个状态下,已经输入了数字并带有小数点。 幂符号状态:在这个状态下,出现了字符 e 或 E。 幂符号后的符号位状态:在这个状态下,出现了符号位 + 或 -。 幂符号后的整数状态:在这个状态下,输入了数字 0-9。 终止状态:如果当前输入的字符不合法或者最后一步能够到达终止状态,则说明输入是一个合法的数字。

class Solution {
public boolean isNumber(String s) {// 定义有限状态自动机Map<State, Map<CharType, State>> transfer = new HashMap<>(); transfer.put(State.STATE_INITIAL, new HashMap<>() {{put(CharType.CHAR_SPACE, State.STATE_INITIAL); // 起始空格状态put(CharType.CHAR_NUMBER, State.STATE_INTEGER); // 整数状态put(CharType.CHAR_SIGN, State.STATE_SIGN); // 符号位状态put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT); // 小数点状态(前面没有数字)}});transfer.put(State.STATE_SIGN, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_INTEGER); // 整数状态put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT); // 小数点状态(前面没有数字)}});transfer.put(State.STATE_INTEGER, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_INTEGER); // 整数状态put(CharType.CHAR_EXP, State.STATE_EXP); // 幂符号状态put(CharType.CHAR_POINT, State.STATE_POINT); // 小数状态put(CharType.CHAR_SPACE, State.STATE_END); // 终止状态}});transfer.put(State.STATE_POINT, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_FRACTION); // 小数状态put(CharType.CHAR_EXP, State.STATE_EXP); // 幂符号状态put(CharType.CHAR_SPACE, State.STATE_END); // 终止状态}});transfer.put(State.STATE_POINT_WITHOUT_INT, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_FRACTION); // 小数状态}});transfer.put(State.STATE_FRACTION, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_FRACTION); // 小数状态put(CharType.CHAR_EXP, State.STATE_EXP); // 幂符号状态put(CharType.CHAR_SPACE, State.STATE_END); // 终止状态}});transfer.put(State.STATE_EXP, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER); // 幂符号后的整数状态put(CharType.CHAR_SIGN, State.STATE_EXP_SIGN); // 幂符号后的符号位状态}});transfer.put(State.STATE_EXP_SIGN, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER); // 幂符号后的整数状态}});transfer.put(State.STATE_EXP_NUMBER, new HashMap<>() {{put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER); // 幂符号后的整数状态put(CharType.CHAR_SPACE, State.STATE_END); // 终止状态}});transfer.put(State.STATE_END, new HashMap<>() {{put(CharType.CHAR_SPACE, State.STATE_END); // 终止状态}});// 根据定义的状态转移规则,判断该字符串是否为有效数字int length = s.length();State state = State.STATE_INITIAL;for (int i = 0; i < length; i++) {CharType type = toCharType(s.charAt(i));if (!transfer.get(state).containsKey(type)) { // 当前输入不合法return false;}state = transfer.get(state).get(type); // 进入下一个状态}// 最后一步能够到达终止状态说明该字符串是一个有效数字return state == State.STATE_INTEGER || state == State.STATE_POINT ||state == State.STATE_FRACTION || state == State.STATE_EXP_NUMBER ||state == State.STATE_END;
}// 定义字符类型枚举类
enum CharType {CHAR_NUMBER,CHAR_EXP,CHAR_POINT,CHAR_SIGN,CHAR_SPACE,CHAR_ILLEGAL
}// 判断字符类型
private CharType toCharType(char ch) {if (ch >= '0' && ch <= '9') {return CharType.CHAR_NUMBER;} else if (ch == 'e' || ch == 'E') {return CharType.CHAR_EXP;} else if (ch == '.') {return CharType.CHAR_POINT;} else if (ch == '+' || ch == '-') {return CharType.CHAR_SIGN;} else if (ch == ' ') {return CharType.CHAR_SPACE;} else {return CharType.CHAR_ILLEGAL;}
}// 定义状态枚举类
enum State {STATE_INITIAL,STATE_INTEGER,STATE_POINT,STATE_POINT_WITHOUT_INT,STATE_FRACTION,STATE_EXP,STATE_EXP_SIGN,STATE_EXP_NUMBER,STATE_SIGN,STATE_END
}
}

复杂度分析:

  • 时间复杂度为O(n),其中n表示字符串的长度。算法需要对字符串中的每个字符进行遍历,因此时间复杂度与字符串的长度成正比。
  • 空间复杂度为O(1),因为算法只使用了常数个变量和一个固定大小的哈希表(状态转移规则),不随输入规模的增加而增加额外的空间消耗。因此,算法的空间复杂度是常数级别的。

LeetCode运行结果:

方法二:正则表达式

除了有限状态自动机,还可以使用正则表达式来判断一个字符串是否为有效数字。Java中提供了一个函数matches(String regex)来判断一个字符串是否能够匹配指定的正则表达式。

class Solution {
public boolean isNumber(String s) {// 使用正则表达式匹配字符串return s.trim().matches("[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[Ee][+-]?\\d+)?");
}
}

复杂度分析:

该算法的时间复杂度为O(1),因为使用了Java内置函数,时间复杂度是固定的。空间复杂度为O(1),因为没有使用额外的空间。

需要注意的是,使用正则表达式虽然代码简单易懂,但是性能可能不如有限状态自动机。正则表达式求解的时间复杂度是O(n),其中n是字符串长度,适用于一些简单的模式匹配。对于复杂模式,引擎会消耗非常多的时间和空间,建议在使用时注意性能问题。

LeetCode运行结果:

第三题

题目来源

66. 加一 - 力扣(LeetCode)

题目内容

解决方法

方法一:从最后一位向前遍历

该方法从数组的最后一位开始向前遍历,将当前位加一,如果加一后不需要进位,则直接返回结果。如果加一后需要进位,则将当前位置为0,并继续处理前一位。如果所有位都需要进位,则返回新的结果数组,长度为原数组长度加一,首位为1,其余位为0。

class Solution {
public int[] plusOne(int[] digits) {int n = digits.length;// 从最后一位开始向前遍历for (int i = n - 1; i >= 0; i--) {// 当前位加一digits[i]++;// 如果当前位加一后仍然小于10,没有进位,直接返回结果if (digits[i] < 10) {return digits;}// 有进位,当前位变为0,继续处理前一位digits[i] = 0;}// 若所有位都有进位,则数组长度需要增加1,首位为1,后面全是0int[] result = new int[n + 1];result[0] = 1;return result;
}}

复杂度分析:

  • 时间复杂度:O(n),其中n为数组的长度。在最坏情况下,需要遍历整个数组一次。
  • 空间复杂度:O(n),需要创建一个新的结果数组,长度可能为n+1。

LeetCode运行结果:

方法二:数学运算

还可以使用数学运算来实现加一操作。

  1. 首先将数组最后一位加一,记录进位carry。
  2. 从数组倒数第二位开始,将当前位加上进位carry,并更新进位carry。
  3. 如果进位carry为0,则无需继续处理,直接返回结果数组。
  4. 如果进位carry不为0,则继续向前处理前一位。
  5. 如果处理完所有位后,进位carry仍然不为0,说明需要扩展结果数组的长度,将原数组复制到新的结果数组中,并在首位插入进位carry。
class Solution {
public int[] plusOne(int[] digits) {int n = digits.length;int carry = 1; // 进位初始化为1// 从数组最后一位开始计算for (int i = n - 1; i >= 0; i--) {digits[i] += carry; // 当前位加上进位carry = digits[i] / 10; // 计算新的进位digits[i] %= 10; // 当前位取模,得到个位数// 如果进位为0,说明不需要再进位,直接返回结果数组if (carry == 0) {return digits;}}// 若所有位都有进位,则数组长度需要增加1,首位为进位carry,后面全是0int[] result = new int[n + 1];result[0] = carry;System.arraycopy(digits, 0, result, 1, n);return result;
}}

复杂度分析:

  • 时间复杂度:遍历数组需要线性时间O(n),其中每个元素只进行一次常数级别的数学运算,所以总体时间复杂度也是O(n)。
  • 空间复杂度:除了原数组外,需要在进位的情况下创建一个新数组来存储结果,所以空间复杂度为O(n)。

LeetCode运行结果:

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

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

相关文章

测试除了点点点,还有哪些内容呢?

今天和一个网友讨论了一下关于互联网行业中测试的情况&#xff0c;希望能够了解现在的互联网行业主要的测试工作内容。小编根据以往的工作经历和经验情况&#xff0c;来做一个总结和整理。 1、岗位分类 现在的岗位划分主要是分为两大类&#xff1a;测试工程师 和 测试开发工程…

matlab相机标定实验

实验原理 1. 相机标定坐标系 相机的参数对目标的识别、定位精度有很大的影响&#xff0c;相机标定就是为了求出相机的内外参数。标定中有3个不同层次的坐标系&#xff1a;世界坐标系、相机坐标系和图像坐标系&#xff08;图像物理坐标系和图像像素坐标系&#xff09;。世界坐…

数据结构--》掌握数据结构中的排序算法

当我们面对海量数据时&#xff0c;如何高效地将其排序是数据结构领域中一个重要的问题。排序算法作为其中的关键部分&#xff0c;扮演着至关重要的角色。 无论你是初学者还是进阶者&#xff0c;本文将为你提供简单易懂、实用可行的知识点&#xff0c;帮助你更好地掌握排序算法在…

pdf怎么压缩?pdf文件缩小的方法在这里

PDF文件由于其跨平台、可打印性强等特点&#xff0c;成为了我们日常工作中经常使用的一种文件格式。然而&#xff0c;这种格式的文件有时候会因为过于庞大而给我们的存储和传输带来困扰&#xff0c;其实&#xff0c;这种情况只需要通过一些工具对PDF文件进行压缩&#xff0c;即…

【RocketMQ系列二】通过docker部署单机RocketMQ

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

小程序uView2.X框架upload组件上传方法总结+避坑

呈现效果: 1.1单图片上传 1.2多图片上传 前言:相信很多人写小程序会用到uView框架,总体感觉还算OK吧,只能这么说,肯定也会遇到图片视频上传,如果用到这个upload组件相信你,肯定遇到各种各样的问题,这是我个人总结的单图片和多图片上传方法. uView2.X框架:uView 2.0 - 全面兼容…

4.Python-用Python,Ajax实现MySQL数据库的新增数据

题记 用python&#xff0c;ajax实现mysql数据库的新增数据。以下是一个简单的实例和操作过程。 安装flask模块 pip install flask 安装mysql.connector模块 pip install mysql-connector-python 编写app.py文件 app.py文件如下&#xff1a; 块引用可能显示不完整&#x…

一键切换IP地址:电脑IP更改的简便方法

今天我要和大家分享一个电脑IP更改的简便方法——一键切换IP地址。如果您想要更改电脑的IP地址&#xff0c;无需繁琐的设置和复杂的步骤&#xff0c;只需使用以下简单的方法&#xff0c;即可轻松实现IP地址的切换。让我们开始吧&#xff01; 1、使用批处理脚本 批处理脚本是一…

java项目之学生综合考评管理系统()

项目简介 学生综合考评管理系统实现了以下功能&#xff1a; 管理员&#xff1a;个人中心、通知公告管理、班级管理、学生管理、教师管理&#xff0c;课程信息管理、作业布置管理、作业提交管理、留言信息管理、课程成绩管理。学生&#xff1a;个人中心、通知公告管理、教师管…

OpenCV学习笔记-环境搭建

文章目录 概述下载安装Visual Studio 2022下载安装OpenCVVisual Studio 配置配置包含路径配置库路径配置链接器配置环境变量Path路径 测试C测试Python 测试 概述 OpenCV&#xff08;Open source computer vision&#xff09;是一个跨平台的计算机视觉和机器学习开源库&#xf…

详解RocketMQ消息存储原理

本文基于RocketMQ 4.6.0进行源码分析 一. 存储概要设计 RocketMQ存储的文件主要包括CommitLog文件、ConsumeQueue文件、Index文件。RocketMQ将所有topic的消息存储在同一个文件中&#xff0c;确保消息发送时按顺序写文件&#xff0c;尽最大的能力确保消息发送的高性能与高吞吐…

旅游票务商城小程序的作用是什么

随着环境放开&#xff0c;旅游行业恢复了以往的规模&#xff0c;本地游、外地游成为众多用户选择&#xff0c;而在旅游时&#xff0c;不少人会报名旅行团前往各风景热点游玩&#xff0c;对旅游票务经营者而言&#xff0c;市场高需求的同时也面临一些难题。 对旅游票务经营商家…

四、RIP动态路由实验

拓扑图&#xff1a; 基本ip的配置已经配置好了&#xff0c;接下来对两台路由器配置rip协议&#xff0c;两台PC进行跨网段通讯 RIPv1版本只能识别ABC的大类网段&#xff0c;不能区分子网掩码&#xff0c;v2版本可以识别子网掩码 首先进入R1&#xff0c;进入rip&#xff0c;宣告…

springboot 使用RocketMQ客户端生产消费消息DEMO

创建springboot项目省略 项目依赖 注意&#xff1a;当前客户端版本是 5.1.3 &#xff0c;安装的rocketmq服务的版本要与其对应 <properties><java.version>11</java.version><rocketmq-client-java-version>5.1.3</rocketmq-client-java-version&…

Annoy vs Milvus:哪个向量数据库更适合您的AI应用?知其然知其所以然

1. Annoy vs Milvus简介 Annoy 和 Milvus 都是用于向量索引和相似度搜索的开源库&#xff0c;它们可以高效地处理大规模的向量数据。 Annoy&#xff08;Approximate Nearest Neighbors Oh Yeah&#xff09;&#xff1a; Annoy 是一种近似最近邻搜索算法&#xff0c;它通过构…

Flink中KeyBy、分区、分组的正确理解

1.Flink中的KeyBy 在Flink中&#xff0c;KeyBy作为我们常用的一个聚合类型算子&#xff0c;它可以按照相同的Key对数据进行重新分区&#xff0c;分区之后分配到对应的子任务当中去。 源码解析 keyBy 得到的结果将不再是 DataStream&#xff0c;而是会将 DataStream 转换为 Key…

同源策略和跨域问题

1.跨域问题产生的原因 浏览器的同源策略影响&#xff0c;同源策略是一种安全机制&#xff0c;它限制了一个网页中的脚本只能访问同源的资源。 跨源网络访问的三种方式&#xff1a;跨域写操作&#xff0c;跨域资源嵌入&#xff0c;跨域读操作 2.跨域问题案例 ip和域名不一致…

微信小程序底部tabBar不显示图标

现场还原 在设置微信小程序底部tabBar导航图标时&#xff0c;无论如何操作均无法显示在界面上 解决思路 问题1 图标类型 一开始以为不支持png类型&#xff0c;但查看官方API仅提示ICON尺寸大小 打开其他项目可以正常展示&#xff0c;排除图标类型问题 iconPath string 否 …

UE4和C++ 开发-常用的宏(二)UPROPERTY(类似于Unity中C#的特性[SerializeField])

UPROPERTY的作用类似于Unity中C#的特性[SerializeField]或者Godot中的export。目的就是通过反射把属性暴露在蓝图或实例的细节面板。 属性说明符&#xff08;Property Specifiers&#xff09;

unity2022版本 实现手机虚拟操作杆

简介 在许多移动游戏中&#xff0c;虚拟操纵杆是一个重要的用户界面元素&#xff0c;用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆&#xff0c;提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆&#xff0c;如固定和跟随&#xff0c;以及如…