【LeetCode热题100】打卡第32天:最长连续序列只出现一次的数字单词拆分环形链表

文章目录

  • 【LeetCode热题100】打卡第32天:最长连续序列&只出现一次的数字&单词拆分&环形链表
    • ⛅前言
  • 最长连续序列
    • 🔒题目
    • 🔑题解
  • 只出现一次的数字
    • 🔒题目
    • 🔑题解
  • 单词拆分
    • 🔒题目
    • 🔑题解
  • 环形链表I
    • 🔒题目
    • 🔑题解

【LeetCode热题100】打卡第32天:最长连续序列&只出现一次的数字&单词拆分&环形链表

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

最长连续序列

🔒题目

原题链接:128.最长连续序列

image-20230702123204636

🔑题解

  • 解法一:排序

    class Solution {public int longestConsecutive(int[] nums) {int len = nums.length;if (len <= 1){return len == 0 ? 0 : 1;}Arrays.sort(nums);int i = 1;int max = 0;int count = 1;while (i < len) {int dif = nums[i] - nums[i - 1];if (dif == 1) {// 差值为1,相邻元素连续count++;} else if (dif == 0) {// 差值为0,相邻元素相同} else {// 相邻元素有间隔,重新计数count = 1;}i++;max = Math.max(max, count);}return max;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn),Arrays.sort内部实现是快排,时间复杂度是 n l o g n nlogn nlogn,while循环的时间复杂度是 n n n,所以总的来说的 n l o g n n nlognn nlognn
    • 空间复杂度: O ( 1 ) O(1) O(1),没有占用额外的空间,空间开销是常数

    其中 n n n 为数组中元素的个数

    PS:这段代码的时间复杂度没有达到 O ( n ) O(n) O(n),但是经过提交发现时间和空间的占用居然还超过了官方时间复杂度为 O ( n ) O(n) O(n)的代码😳,这可能是示例数据的原因,一般而言并不是说时间复杂度越高效率就越第(比如动态规划时间复杂度可能有 O ( n 2 ) O(n^2) O(n2),但可能比一些时间复杂度为 O ( n ) O(n) O(n)的代码还要快,这里也是一样)

  • 解法二:哈希表

    通过Set集合去重,然后利用contains方法检索下一个数是否在Set集合中,但是会发现居然超时了!

    class Solution {public int longestConsecutive(int[] nums) {// 利用Set集合进行去重Set<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {set.add(nums[i]);}int max = 0;for (Integer i : set) {int count = 1;int next = i + 1;while (set.contains(next)) {// 当前数字的后一个数字在Set集合中,len+1next++;count++;}max = Math.max(max, count);}return max;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为数组中元素的个数

    代码优化:时间优化

    上面代码超时了,这是由于出现了大量重复的计算,比如:Set集合中是{1,2,3,6,7,9},在计算元素 1 的最大连续数时,其实就已经计算过了 2 和 3 的最大连续数,所以这里我们可以进行一个过滤(有点像剪枝操作),避免重复计算,那么该如何过滤呢?其实我们只需要 添加一个 !set.contains(i-1)即可,也就是如果当前元素的上一个数在Set集合中存在,就说明当前元素的最大连续值已经计算过了

    class Solution {public int longestConsecutive(int[] nums) {// 利用Set集合进行去重Set<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {set.add(nums[i]);}int max = 0;for (Integer i : set) {int count = 1;if (!set.contains(i - 1)) {int next = i + 1;while (set.contains(next)) {// 当前数字的后一个数字在Set集合中,count+1next++;count++;}}// 更新最大连续序列的长度max = Math.max(max, count);}return max;}
    }
    
  • 解法三:动态规划

    略……详情参考【超小白】哈希集合/哈希表/动态规划/并查集四种方法,绝对够兄弟们喝一壶的! - 最长连续序列 - 力扣(LeetCode)

  • 解法四:并查集

    略……感兴趣的可以参考上面的链接

只出现一次的数字

🔒题目

原题链接:136.只出现一次的数字

image-20230704221911611

🔑题解

  • 解法一:暴力

    这种暴力是我最开始想到的,利用map进行映射时间复杂度相对较小,还有一种更加暴力的方法双重for循环,时间复杂度高达 O ( n 2 ) O(n^2) O(n2)

    class Solution {public int singleNumber(int[] nums) {Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int value = map.getOrDefault(nums[i], 0);if (value <= 1) {map.put(nums[i], value + 1);}}int ans = 0;for (int key : map.keySet()) {int value = map.get(key);if (value == 1) {ans = key;}}return ans;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为数组中元素的个数

  • 解法二:排序

    class Solution {public int singleNumber(int[] nums) {Arrays.sort(nums);int ans = Integer.MIN_VALUE;for (int i = 0; i < nums.length-2; i+=2) {if (nums[i] != nums[i + 1]) {ans = nums[i];break;}}return ans == Integer.MIN_VALUE ? nums[nums.length-1] : ans;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn),Arrays.sort底层是快排,快排的时间复杂度是 n l o g n nlogn nlogn
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

  • 解法三:位运算(按位异或)

    这个太强了,没有想到这方面,但是一看就豁然开朗(只能说见识太短了,或者说经验不足)。我们需要明确异或^运算的特点:同为假(同真同假都为假),不同为真(一真一假为真),通过它的特点我们可以有以下结论:

    1. 交换律:a^b^c=a^c^b
    2. 与0异或结果为本身:0^n=n
    3. 相同数异或为0:n^n=0
    class Solution {public int singleNumber(int[] nums) {int ans = 0;for (int i : nums) {ans ^= num;}return ans;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为数组中元素的个数

单词拆分

🔒题目

原题链接:139.单词拆分

image-20230705124017764fi

🔑题解

  • 解法一:DFS(超时,36/46,10个用例没通过)

    DFS 解题示意图:

    class Solution {private boolean f = false;public boolean wordBreak(String s, List<String> wordDict) {StringBuilder path = new StringBuilder();dfs(s, wordDict, path);return f;}private void dfs(String s, List<String> wordDict, StringBuilder path) {if (s.equals(path.toString())){// 当前路径组成了目标值,结束递归f = true;return;}if (path.length()> s.length() || !s.substring(0, path.length()).equals(path.toString())){// 当前路径组成字符串的长度超过了目标值长度// 当前路径组成字符串的最后字符不等于目标值最后那段字符return;}for (int i = 0; i < wordDict.size(); i++) {String str = wordDict.get(i);path.append(str);// 往下遍历下一个节点dfs(s, wordDict, path);// 恢复现场,用户回溯path.delete(path.length()-str.length(), path.length());}}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ) O(n*m) O(nm),在每个递归步骤中,我们都要遍历整个字典 wordDict 中的单词。所以,对于每个单词,我们需要执行一次递归调用。因此,总的递归调用次数是 O(N),其中 n 是字典中的单词数量。除此之外,我们还需要比较字符串 s 的前缀和当前路径 path 的前缀,这需要 O(m) 的时间,其中 m 是字符串 s 的长度。因此,该算法的时间复杂度为 O(n*m)
    • 空间复杂度: O ( m ) O(m) O(m),递归的最大深度应该是 m m m,所以空间复杂度是 O ( m ) O(m) O(m)

    其中 n n n 为字典中单词的数量, m m m是字符串的长度

    代码优化:时间优化

    前面直接使用暴力DFS超时了,所以我们需要对DFS进行优化,而DFS优化策略一般是剪枝,这里我们需要使用 记忆索索

    实现剪枝,具体代码如下:

    
    
  • 解法二:哈希表

    这个太强了,时间复杂度直接变成 O ( n ) O(n) O(n),它是利用Map的Key不能重复的特性,来判断元素是否符合要求。

    
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为数组中元素的个数

环形链表I

🔒题目

原题链接:141.环形链表I

image-20230705135602114

🔑题解

  • 解法一:快慢指针

    由于这个题目是二刷了,所以顺其自然以下就想到了快慢指针这个解法,这个类似于物理里面的相对速度,一个指针比另一个指针要快一个速度,这样如果链表中有环,快指针一定会出现在慢指针的后面,如果没有环则快指针直接就到底了,实现起来也比较简单😄,看来坚持每天刷题还是有一定作用的,不至于遇到这个题目没有任何的思绪

    public class Solution {public boolean hasCycle(ListNode head) {if (head == null) {return false;}ListNode slow = head;ListNode fast = head;while (fast != null) {if (fast.next == slow) {// fast走到了slow的后面,说明链表中有环return true;}slow = slow.next;// fast比slow多走一步fast = fast.next;if (fast != null){// 防止NPEfast = fast.next;}}return false;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为链表中节点的数量

  • 解法二:利用Set集合不重复的特点

    这种方式十分的暴力简单🤣,效率没有快慢指针快

    public class Solution {public boolean hasCycle(ListNode head) {Set<ListNode> seen = new HashSet<>();while (head != null) {if (!seen.add(head)) {return true;}head = head.next;}return false;}
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为链表中节点的数量

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

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

相关文章

mysql管理

目录 一、数据库的组成 1.数据 (Data) 2. 表 3. 数据库 二、数据库系统 1.数据库管理系统(DBMS) 2. 数据库系统&#xff08;DBS&#xff09; 3. DBMS的工作模式 三、数据库系统发展史 1.第一代数据库&#xff08;人工管理&#xff09; 2. 第二代数据库&#xff08…

C++线性表、单链表

概述 在先说链表前&#xff0c;我们先来理清几个概念。 什么是线性表、顺序表和链表&#xff1f;三者有什么关系&#xff1f; 线性表&#xff1a;元素线性排列&#xff0c;在逻辑上具有次序的存储结构。 顺序表&#xff1a;线性表的顺序存储称为线性表。它是用一组地址连续(逻…

Windows server 2012服务器远程桌面登录时出现错误提示:“由于没有远程桌面授权服务器可以提供许可证,远程会话被中断

简单粗暴&#xff1a; Windows server 2012服务器远程桌面登录时出现错误提示&#xff1a;“由于没有远程桌面授权服务器可以提供许可证&#xff0c;远程会话被中断。请跟服务器管理员联系 使用 mstsc /admin /v:目标ip 来强制登录服务器&#xff0c;但只能是管理员身份…

【C++修炼之路】31.异常

每一个不曾起舞的日子都是对生命的辜负 异常 一.C语言传统的处理错误的方式二.C异常概念三.异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 四.自定义异常体系五.C标准库的异常体系六.异常的优缺点 一.C语言传统的处理错误的方式 传统的错误处理机…

Appium+python自动化(一)- 环境搭建—上(超详解)

最近整理了一下自动化的东西&#xff0c;先前整理的python接口自动化已经接近尾声。即将要开启新的征程和篇章&#xff08;Appium&python&#xff09;。那么首相的问题就是搭建环境了。好久没搭建环境又踩了不少坑&#xff0c;appium的环境搭建比较繁琐&#xff0c;好多同行…

picard安装时报错“Exception in thread “main“ java.lang.UnsupportedClassVersionError”

最近在通过GATK所介绍的best practice流程来call SNP流程 1.流程 1.1 BWA比对&#xff0c;获得sam文件 1.2 准备用picard来压缩排序sam文件为bam文件&#xff0c;并对bam文件进行去重复&#xff08;duplicates marking&#xff09; 这是就需要用到picard软件 按照教程网页上…

Centos安装指定docker版本和docker-compose

目录 一. 直接安装Docker最新镜像源 1. 卸载旧版本的Docker&#xff1a; 2. 安装依赖包&#xff1a; 3. 添加Docker源&#xff1a; 4. 安装Docker&#xff1a; 5. 启动Docker服务&#xff1a; 6. 验证Docker是否安装成功&#xff1a; 二、指定Docker版本安装 1. 查看…

软件设计模式与体系结构-软件体系-调用-返回风格软件体系结构

目录 软件体系结构概述概述 一、调用-返回风格软件体系结构概念代码主程序-子程序软件体系结构自顶向下的设计方法的问题结构化设计的优缺点面向对象体系结构面向对象设计的优缺点主程序-子程序与面向对象体系结构相似差异 课程作业 软件体系结构概述 调用-返回风格软件体系结…

论文 | 一分钟快速找到自己研究领域的核心期刊

进入知网官网 https://www.cnki.net/ 点击搜索框右边的&#xff1a;出版物检索 鼠标放到顶部的 出版来源导航 旁边的倒三角上 选择期刊导航&#xff1a; 点击核心期刊导航 找到自己感兴趣的领域 点进去就可以看到该期刊中发表的论文&#xff1a;

ChatGPT训练流程

图源&#xff1a;State of GPT - Microsoft Build 笔者翻译上图如下&#xff1a; 阶段子阶段目标备注Pre-Training--------语言建模Instruction Finetuning---------让模型能够理解自然语言指令RLHFReward Modeling奖励建模&#xff0c;用来代替人工打分&#xff0c;降低标注…

8-1、Deployment运行应用的机制

Kubernetes 通过各种 Controller 来管理 Pod 的生命周期。为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 、 CronJob 等多种 Controller。 用户通过 kubectl 创建 Depl…

数据结构【考研笔记】

数据结构【考研笔记】 第一章 绪论一、数据结构的基本概念1、基本概念1&#xff09;数据2&#xff09;数据元素、数据项3&#xff09;数据对象、数据结构4&#xff09;数据类型、抽象数据类型&#xff08;ADT&#xff09; 2、三要素1&#xff09;逻辑结构2&#xff09;存储结构…