怒刷LeetCode的第8天(Java版)

目录

第一题

题目来源

题目内容

解决方法

方法一:双指针和排序

​编辑第二题

题目来源

题目内容

解决方法

方法一:双指针

方法二:递归

方法三:快慢指针

方法四:栈

第三题

题目来源

题目内容

解决方法

方法一:栈


第一题

题目来源

18. 四数之和 - 力扣(LeetCode)

题目内容

解决方法

方法一:双指针和排序

根据题目要求,可以使用双指针和排序法来解决这个问题。

使用双指针解决四数之和问题的算法思路如下:

1、对数组进行排序,将其从小到大排列。

2、使用两重循环分别枚举前两个数,其中第一个数的下标范围是0到n-4,第二个数的下标范围是第一个数的下标加1到n-3。

4、在两重循环中,使用双指针分别指向当前枚举的两个数之后的位置。

5、每次计算四个数的和,并根据和与目标值的比较结果进行如下操作:

  • 如果和等于目标值,将四个数加入答案。
  • 如果和小于目标值,将左指针右移一位。
  • 如果和大于目标值,将右指针左移一位。
  • 同时,如果左指针或右指针指向的数字与上一次迭代的数字相同,继续移动指针直到遇到不同的数字。

6、循环结束后,返回所有符合条件的四个数的组合。

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> quadruplets = new ArrayList<List<Integer>>();if (nums == null || nums.length < 4) {return quadruplets;}Arrays.sort(nums);int length = nums.length;for (int i = 0; i < length - 3; i++) {if (i > 0 && nums[i] == nums[i - 1]) {continue;}if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {break;}if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {continue;}for (int j = i + 1; j < length - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1]) {continue;}if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {break;}if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {continue;}int left = j + 1, right = length - 1;while (left < right) {long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];if (sum == target) {quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));while (left < right && nums[left] == nums[left + 1]) {left++;}left++;while (left < right && nums[right] == nums[right - 1]) {right--;}right--;} else if (sum < target) {left++;} else {right--;}}}}return quadruplets;}
}

复杂度分析:

  • 时间复杂度为O(n^3),其中n是数组的长度。这是因为代码中有两重循环,加上双指针的遍历,总的时间复杂度为O(n^2)。而在双指针的遍历过程中,左右指针最多各自遍历一次数组,所以时间复杂度为O(n)。
  • 空间复杂度方面,代码只使用了常数级别的额外空间,主要是存储结果列表,所以空间复杂度为O(1)。

总结起来,该算法的时间复杂度为O(n^3),空间复杂度为O(1)。需要注意的是,在代码中已经进行了一些剪枝操作,以优化算法的效率。

LeetCode运行结果:

第二题

题目来源

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

题目内容

解决方法

方法一:双指针

这道题可以使用双指针来实现。具体做法是,先让第一个指针往前移动n个位置,然后同时移动第一个指针和第二个指针,直到第一个指针到达链表尾部。此时,第二个指针所指向的节点就是要删除的节点的前一个节点,我们只需要将该节点的next指针指向下一个节点,即可完成删除操作。

需要注意的几点是:

  • 要处理删除头结点的情况;
  • 链表中可能只有一个节点。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {if (head == null) {return null;}ListNode dummy = new ListNode(0, head);ListNode first = head;ListNode second = dummy;for (int i = 0; i < n; i++) {first = first.next;}while (first != null) {first = first.next;second = second.next;}second.next = second.next.next;return dummy.next;
}}

复杂度分析:

  • 对于给定的链表,我们只需要进行一次遍历即可找到要删除的节点的前一个节点。因此,时间复杂度为O(n),其中n是链表的长度。
  • 在空间复杂度方面,我们只使用了常数级别的额外空间,主要是两个指针变量和一个虚拟头节点。因此,空间复杂度为O(1)。

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

LeetCode运行结果:

方法二:递归

除了双指针法之外,我们还可以使用递归来解决这个问题。具体做法是,在递归的过程中,使用一个计数器来记录当前遍历到的节点位置,并从链表的末尾开始向前遍历。当计数器等于n时,将当前节点的next指针指向下一个节点的next指针,即完成删除操作。

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {if (head == null) {return null;}int count = removeHelper(head, n);// 如果计数器等于n,表示要删除的是头结点if (count == n) {return head.next;}return head;
}private int removeHelper(ListNode node, int n) {if (node == null) {return 0;}int count = removeHelper(node.next, n) + 1;// 如果计数器等于n+1,表示要删除的是当前节点的下一个节点if (count == n + 1) {node.next = node.next.next;}return count;
}
}

该方法的思路是通过递归实现回溯,每次递归返回当前节点所处的位置。在返回的过程中,不断判断计数器的值是否等于n或n+1,并进行相应的删除操作。

复杂度分析:

  • 时间复杂度:在递归过程中,需要遍历整个链表,即O(n)次递归调用。每次递归操作都需要O(1)的时间,因此总体时间复杂度为O(n)。
  • 空间复杂度:递归调用会占用栈空间,最坏情况下,递归的深度为链表的长度n,因此空间复杂度为O(n),除去递归栈空间外,不需要额外的空间。

LeetCode运行结果:

方法三:快慢指针

另一种常见的思路是使用快慢指针。首先,我们让快指针向前移动n个位置。然后,同时移动快指针和慢指针,直到快指针达到链表尾部。此时,慢指针所指的节点就是要删除的节点的前一个节点,我们只需将其next指针指向下一个节点,即可完成删除操作。

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {if (head == null) {return null;}ListNode dummy = new ListNode(0, head);ListNode fast = dummy;ListNode slow = dummy;// 快指针先向前移动n个位置for (int i = 0; i < n; i++) {fast = fast.next;}// 同时移动快慢指针,直到快指针达到链表尾部while (fast.next != null) {fast = fast.next;slow = slow.next;}// 删除目标节点slow.next = slow.next.next;return dummy.next;
}}

该方法的思路是通过快慢指针的差距来定位要删除的节点的前一个节点。快指针先向前移动n个位置,然后同时移动快慢指针,直到快指针到达链表尾部。这样,慢指针所指的节点就是要删除的节点的前一个节点。 

复杂度分析: 

  • 时间复杂度:需要遍历整个链表,除了初始化指针外,只需一次遍历即可完成任务。因此时间复杂度为O(n)。
  • 空间复杂度:只使用了常数级别的额外空间,即定义的指针变量,因此空间复杂度为O(1)。

注意:递归解法和快慢指针解法的时间复杂度都是O(n),其中递归解法的空间复杂度为O(n),而快慢指针解法的空间复杂度为O(1)。因此,在大多数情况下,推荐使用快慢指针解法,因为它的空间复杂度更低。

LeetCode运行结果:

方法四:栈

  • 首先,遍历链表并将每个节点都压入栈中。
  • 然后,从栈顶开始弹出节点,同时计数。
  • 当计数等于n时,表示栈顶节点就是要删除的节点。此时,只需修改相应的指针即可完成删除操作。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {if (head == null) {return null;}Stack<ListNode> stack = new Stack<>();ListNode dummy = new ListNode(0);dummy.next = head;ListNode current = dummy;// 将链表节点依次压入栈中while (current != null) {stack.push(current);current = current.next;}// 弹出第n个节点,并删除for (int i = 0; i < n; i++) {stack.pop();}ListNode prev = stack.peek();prev.next = prev.next.next;return dummy.next;
}
}

复杂度分析:

  • 时间复杂度:遍历链表将节点压入栈中需要O(n)的时间,弹出第n个节点并删除需要O(n)的时间,因此总体时间复杂度为O(n)。
  • 空间复杂度:创建了一个栈来存储链表节点,栈的空间消耗取决于链表的长度,所以空间复杂度为O(n)。

综上所述,使用栈解法删除链表中倒数第n个节点的时间复杂度为O(n),空间复杂度为O(n)。相较于快慢指针解法的O(1)的空间复杂度,栈解法的空间复杂度较高。因此,在大多数情况下,推荐使用快慢指针解法。

LeetCode运行结果:

第三题

题目来源

20. 有效的括号 - 力扣(LeetCode)

题目内容

解决方法

方法一:栈

这个问题可以使用栈来解决。我们可以遍历字符串,当遇到左括号时,将其入栈,当遇到右括号时,判断栈顶元素是否与当前右括号匹配。如果匹配,则将栈顶元素出栈,继续遍历;如果不匹配或栈为空,则说明字符串无效。

import java.util.Stack;
class Solution {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {if (c == '(' || c == '{' || c == '[') { // 遇到左括号,入栈stack.push(c);} else if (c == ')' || c == '}' || c == ']') { // 遇到右括号,判断是否匹配if (stack.isEmpty()) {return false; // 栈为空,无法匹配}char top = stack.pop(); // 弹出栈顶元素if ((c == ')' && top != '(') ||(c == '}' && top != '{') ||(c == ']' && top != '[')) {return false; // 括号不匹配}}}return stack.isEmpty(); // 如果栈为空,则所有括号都匹配成功
}
}

复杂度分析:

在遍历字符串时,时间复杂度为O(n),其中n是字符串的长度。同样,使用了一个栈来存储字符,空间复杂度也为O(n)。因此,该解法的时间复杂度和空间复杂度均为O(n)。

LeetCode运行结果:

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

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

相关文章

SSM02

SSM02 此时我们已经做好了登录模块接下来可以做一下学生管理系统的增删改查操作 首先&#xff0c;我们应当有一个登录成功后的主界面 在webapp下新建 1.main.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

天选之子C++是如何发展起来的?如何学习C++呢?

天选之子C是如何发展起来的&#xff1f;如何学习C呢? 一、什么是C二、C发展史三、C的重要性3.1 语言的使用广泛度3.2 在工作领域 四、如何学习C4.1 大佬怎么学&#xff1f;4.2 自己怎么学 一、什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复…

Echarts散点图筛选新玩法dataZoom

目录 前言 一、引入Echarts5.4.3 二、新建index.html 三、绑定Echarts展示元素 四、初始数据绑定 五、option设置 六、效果展示 七、参数说明 总结 前言 如果您在日常的工作当中也会遇到如下场景&#xff0c;需要在线对已经展示出来的图表进行进一步的筛选&#xff0c…

在编译源码的环境下,搭建起Discuz!社区论坛和WordPress博客的LNMP架构

目录 一.编译安装nginx 二.编译安装MySQL 三.编译安装PHP 四.安装论坛 五.安装wordpress博客 六.yum安装LNMP架构&#xff08;简要过程参考&#xff09; 一.编译安装nginx 1&#xff09;关闭防火墙&#xff0c;将安装nginx所需软件包传到/opt目录下 systemctl stop fire…

mysql表的导出和导入

表的导出 mysql 默认对导出的目录有权限限制&#xff0c;也就是说使用命令进行导出的时候&#xff0c;需要指定目录进行操作 show global variables like ‘%secure%’; secure_file_priv 值情况分析&#xff1a; 如果设置为empty&#xff0c;表示不限制文件生成的位置&#x…

Redis 三种特殊的数据类型 - Geospatial地理位置 - Hyperloglog基数统计的算法 - Bitmaps位图(位存储)

目录 Redis 三种特殊的数据类型&#xff1a; Geospatial&#xff1a;地理位置 Geospatial类型常用的命令&#xff1a; GEOADD&#xff1a;添加地理位置 GEOPOS&#xff1a;获取地理位置 GEODIST&#xff1a;返回两个给定位置之间的距离 GEORADIUS&#xff1a;以给定的经纬…

企业电子招投标采购系统——功能模块功能描述+数字化采购管理 采购招投标

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

compose——底部弹窗ModalBottomSheetLayout

底部弹窗ModalBottomSheetLayout ModalBottomSheetLayout 是 Jetpack Compose 中的一个组件&#xff0c;用于创建底部弹窗。它可以在屏幕底部显示一个半透明的背景&#xff0c;并从底部滑出一个内容面板。ModalBottomSheetLayout 包含两个主要部分&#xff1a;背景和内容面板。…

uqrcode+uni-app 微信小程序生成二维码

使用微信小程序需要弹出动态二维码的需求&#xff0c;从插件市场选了一个下载次数较多的组件引入到项目中uqrcode&#xff0c;使用步骤如下&#xff1a; 1、从插件市场下载 插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id1287&#xff0c;若你是跟我一样是用uni-…

java导出Excel合并列(自定义列根据模板进行导出)附详细代码及注解

【版权所有&#xff0c;文章允许转载&#xff0c;但须以链接方式注明源地址&#xff0c;否则追究法律责任】【创作不易&#xff0c;点个赞就是对我最大的支持】 前言 仅作为学习笔记&#xff0c;供大家参考 总结的不错的话&#xff0c;记得点赞收藏关注哦&#xff01; 这里…

DM/达梦数据库查询或更新某一列中多个字典码对应内容

准备工作&#xff08;建表、插入数据&#xff09; 1、建立表格&#xff1a;学生-学习科目表student_study 注意&#xff1a;科目kemu列内容是字典码&#xff0c;需要更换成对应内容。 CREATE TABLE "TEST"."STUDENT_STUDY" ( "NAME" VARCHAR(2…

各种电机驱动原理

步进电机 步进电机参考资料 野火官方文档 步进电机驱动原理 上面参考文档中有的内容就不写了&#xff0c;写一下我自己的总结吧。 说明&#xff1a; 电机驱动器输入信号有电机转动方向信号DIR&#xff0c;电机转速信号PWM&#xff0c;电机使能信号EN&#xff1b;电机驱动器…

安装VS2015时提示安装包丢失或损坏

今天安装VS2015社区版本时&#xff0c;提示缺失以下两个内容&#xff1a; Microsoft VisualStudio JavaScript Project System : 找不到元素。 Microsoft VisualStudio JavaScript Language Service : 系统找不到指定的文件。 虽然似乎不影响C代码的运行&#xff0c;但是我怕有…

计算机网络第四节 数据链路层

一&#xff0c;引入数据链路层的目的 1.目的意义 数据链路层是体系结构中的第二层&#xff1b; 从发送端来讲&#xff0c;物理层可以将数据链路层交付下来的数据&#xff0c;装换成光&#xff0c;电信号发送到传输介质上了 从接收端来讲&#xff0c;物理层能将传输介质的光&…

github 网页显示不全?

问题 解决 1、检查网页&#xff0c;打开 network&#xff0c;重新刷新 github 网页 2、查看无法加载的资源&#xff08;如 css 文件&#xff09; 3、查看域名地址 https://tool.chinaz.com/dns/&#xff0c;github.githubassets.com&#xff08;检查网页元素&#xff0c;点击无…

在Spring Boot API Gateway中实现Sticky Session

文章目录 小结问题在API Gateway中实现Sticky Session在同一个API Gateway中同时支持Sticky Session和RoundRobinLoadBalancer参考 小结 在Kubernetes微服务的云环境中&#xff0c;如何在Spring Boot API Gateway中实现Sticky Session&#xff0c;当服务请求被某一个服务器处理…

2023年7月京东平板电脑行业品牌销售排行榜(京东销售数据分析)

鲸参谋监测的京东平台7月份平板电脑市场销售数据已出炉&#xff01; 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台上平板电脑的销量为68万&#xff0c;同比增长超过37%&#xff1b;销售额为22亿&#xff0c;同比增长约54%。从价格上看…

win系统环境搭建(四)——Windows安装mysql8压缩包版本

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;四&#xff09;——Windows安装mysql8压缩包版本 本系列windows环境搭建开始讲解如何给win系统搭建环境&#xff0c;本人所用系统是腾讯云服务器的Windows Server 2022&#xff0c;你可以理解成就是你用…

mysql知识大全

MySQL知识大全&#xff08;2&#xff09; MySqL 基础为1—7&#xff08;增删改查基础语法&#xff09;&#xff0c;MySQL进阶知识为8—11&#xff08;约束、数据库设计、多表查询、事务&#xff09; 1、数据库相关概念 以前我们做系统&#xff0c;数据持久化的存储采用的是文件…

直线模组的常用语

在工业生产中&#xff0c;直线模组的叫法有很多种&#xff0c;对于新手小白来说&#xff0c;很容易就会被绕晕&#xff0c;今天我们就来简单说一下直线模组的常用称呼吧&#xff01; 1、直线模组&#xff1a;与直线滑台同义&#xff0c;基本可以相互互换。直线模组一般是指可以…