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

news2024/11/16 16:00:26

文章目录

  • 【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+1
                    next++;
                    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+1
                        next++;
                        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){
                    // 防止NPE
                    fast = 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.coloradmin.cn/o/738277.html

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

相关文章

webAPI学习笔记5——移动端网页特效和本地存储

一、移动端网页特效 1. 触屏事件 1.1 触屏事件概述 移动端浏览器兼容性较好&#xff0c;我们不需要考虑以前 JS 的兼容性问题&#xff0c;可以放心的使用原生 JS 书写效果&#xff0c;但是移动端也有自己独特的地方。比如触屏事件 touch&#xff08;也称触摸事件&#xff09…

联想M7605DW怎么连接WiFi网络

联想M7605DW是一款拥有WiFi功能的打印机&#xff0c;可以通过WiFi连接无线网络&#xff0c;实现打印无线传输。 首先&#xff0c;需要确保你的WiFi网络已经正常连接&#xff0c;并且知道WiFI的网络名称和密码&#xff0c;同时确保你的电脑或手机设备与WiFi相连接。 启动联想M76…

数组、指针练习题及解析(含笔试题目讲解)其一

目录 前言 题目列表&#xff1a; 题目解析 一维数组 字符数组 字符串 字符指针 二维数组 笔试题 总结 前言 前几期的博客已经将有关指针、数组的所以知识都已基本讲解完毕&#xff0c;那么接下来我们就做一些练习巩固&#xff0c;这些练习依据历年来一些公司笔试题进行…

java的ThreadLocal变量

Java的ThreadLocal变量是线程的局部变量&#xff0c;只能被本线程访问&#xff0c;不能被其它线程访问&#xff0c;也就是说线程间进行了隔离。每个线程访问该变量的一个独立拷贝&#xff0c;互相不干扰。感觉跟synchronized的作用相反&#xff0c;synchronized是为了保护线程间…

Kafka入门,mysql5.7 Kafka-Eagle部署(二十五)

官网 https://www.kafka-eagle.org/ 下载解压 这里使用的是2.0.8 创建mysql数据库 创建名为ke数据库,新版本会自动创建&#xff0c;不会创建的话&#xff0c;自己手动创建&#xff0c;不然会报查不到相关表信息错误 SET NAMES utf8; SET FOREIGN_KEY_CHECKS 0;-- ------…

从2023中国峰会,看亚马逊云科技的生成式AI战略

“生成式AI的发展就像一场马拉松比赛&#xff0c;当比赛刚刚开始时&#xff0c;如果只跑了三四步就断言某某会赢得这场比赛&#xff0c;显然是不合理的。我们现在还处于非常早期的阶段。” 近日&#xff0c;在2023亚马逊云科技中国峰会上&#xff0c;亚马逊云科技全球产品副总裁…

智慧农业:温室大棚物联网系统,助力实现可视化科学管理

我国传统农业的特点是靠天吃饭&#xff0c;而智慧农业发端于物联网设备和对应的农业信息化管理系统&#xff0c;是利用数字技术、数据分析和人工智能等先进技术手段&#xff0c;对农业生产进行精细化管理和智能化决策的一种新型农业生产模式。它可以通过实时监测、预测和调控土…

java 配置打包Spring Boot项目过程中跳过测试环节

上文 java 打包Spring Boot项目&#xff0c;并运行在windows系统中中 我们演示了打包 Spring Boot项目的并运行在本地的方法 但是 我们这里会看到 每次打包 他这都会有个T E S T S 测试的部分 但是 我们自己开发的程序 要上线 有没有问题我们肯定自己清楚啊 没必要它做测试 而且…

web学习笔记2

文档流 网页是一个多层的结构&#xff0c;设置样式也是一层一层的设置&#xff0c;最终我们看到的最上面的一层。 文档流是网页最底层 我们创建的元素默认情况下&#xff0c;都在文档流中 元素分为两种状态&#xff1a;在文档流中&#xff0c;脱离文档流 元素在文档流中的特点 …

同一段数据分别做傅里叶变化和逆变换的结果及分析

已知有公式 D F T &#xff1a; X [ k ] ∑ n 0 N − 1 x [ n ] e − j 2 π k n N &#xff0c; 0 ≤ k ≤ N − 1 DFT&#xff1a;Χ[k]\sum_{n0}^{N-1}x[n]e^{-\frac{j2\pi kn}{N}}&#xff0c;0≤k≤N-1 DFT&#xff1a;X[k]n0∑N−1​x[n]e−Nj2πkn​&#xff0c;0≤k…

超详细 | 模拟退火-粒子群自适应优化算法及其实现(Matlab)

作者在前面的文章中介绍了经典的优化算法——粒子群算法(PSO)&#xff0c;各种智能优化算法解决问题的方式和角度各不相同&#xff0c;都有各自的适用域和局限性&#xff0c;对智能优化算法自身做的改进在算法性能方面得到了一定程度的提升&#xff0c;但算法缺点的解决并不彻底…

学生公寓智能电表控电系统的技术要求

学生公寓电表智能控电石家庄光大远通电气有限公司模块采用高精度计量芯片,的计量计费功能。 控制路数&#xff1a;可输出1~4路输出,每个回路都可以设置负载识别,定时断送过载功率等控电参数。 自动断电 &#xff1a;具有自动断电功能,可用电量为0时,应自动切断该分路电源 支持正…

创建Spring CloudDEMO流程

创建普通的maven工程作为父工程 然后设置字符集为UTF-8 再注解生效激活 java编译版本选择8 idea文件忽略&#xff08;忽略乱七八糟的文件&#xff09; *.hprof;*.pyc;*.pyo;*.rbc;*.yarb;*~;.DS_Store;.git;.hg;.svn;CVS;__pycache__;_svn;vssver.scc;vssver2.scc;.idea;*.iml…

TencentOS3.1安装PHP+Nginx+redis测试系统

PHP和Nginx应用统一安装在/application下。 Nginx选用了较新的版本1.25.0 官网下载安装包&#xff0c;解包。执行如下命令编译&#xff1a; ./configure --prefix/application/nginx-1.25.0 --usernginx --groupnginx --with-http_ssl_module --with-http_stub_status_modu…

win系统电脑在线打开sketch文件的方法

自Sketch诞生以来&#xff0c;只有Mac版本。Windows计算机如何在线打开Sketch文件&#xff1f; 即时设计已经解决了你遇到的大部分问题&#xff0c;不占用内存也是免费的。 您可以使用此软件直接在线打开Sketch文件&#xff0c;完整预览并导出CSS、SVG、PNG等&#xff0c;还具…

解析JSON格式数据

解析JSON格式数据 比起XML&#xff0c;JSON的体积更小&#xff0c;语义性更差 传入的JSON文件如下 使用JSONObject private fun parseJSONWithJSONObject(jsonData: String) { try { val jsonArray JSONArray(jsonData) for (i in 0 until jsonArray.length()){ val j…

视频去除水印怎么弄?这几个实用方法分享给大家!

在我们观看或分享视频时&#xff0c;可能会遇到一些带有水印的视频。这些水印可能会影响我们的观看体验&#xff0c;或者在我们需要使用这些视频时造成不便。下面&#xff0c;我将为你介绍三种去除视频水印的方法。 方法一&#xff1a;使用记灵在线工具 记灵在线工具是一个非…

Leetcode:684. 冗余连接(并查集C++)

目录 684. 冗余连接 题目描述&#xff1a; 实现代码与解析&#xff1a; 并查集 原理思路&#xff1a; 684. 冗余连接 题目描述&#xff1a; 树可以看成是一个连通且 无环 的 无向 图。 给定往一棵 n 个节点 (节点值 1&#xff5e;n) 的树中添加一条边后的图。添加的边的…

Python安装解释器

文章目录 一、下载Python解释器二. Linux环境的安装三. pycharm创建项目四、验证安装是否成功 一、下载Python解释器 首先&#xff0c;您需要从官方Python网站&#xff08;https://python.org&#xff09;下载Python解释器。Python的当前稳定版本是3.9.x系列。网站上提供了针对…

Anoym:一种以组合质押策略为特点的 LSD 设施

LSD&#xff08;Liquid Staking Derivatives&#xff09;&#xff0c;即流动性质押衍生品&#xff0c;目前主要包括Lido、Frax等主要项目&#xff0c;它是伴随着ETH 2.0升级成长起来的DeFi衍生品赛道。ETH 2.0 以 POS 为共识机制&#xff0c;节点需要质押 32 ETH 才能参与网络维…