【LeetCode热题100】打卡第23天:最小覆盖子集

news2024/11/20 20:27:01

文章目录

  • 【LeetCode热题100】打卡第23天:最小覆盖&子集
    • ⛅前言
  • 最小覆盖
    • 🔒题目
    • 🔑题解
  • 子集
    • 🔒题目
    • 🔑题解

【LeetCode热题100】打卡第23天:最小覆盖&子集

⛅前言

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

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

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

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

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

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

最小覆盖

🔒题目

原题链接:76.最小覆盖子串

image-20230615114454434

🔑题解

  • 解法一:滑动窗口算法

    滑动窗口算法也写了好多遍了,这里就不再多做解释上,直接上代码

    fig1

    PS:上面的动图来自LeetCode官方题解,我感觉特别好,就没有自己制作动图了,直接把它的录制下来了

    滑动窗口主要思路:

    • Step1:定义窗口。定义左右指针,一个是窗口左边界,一个是窗口右边界

    • Step2:滑动窗口。

      1. 扩充窗口,滑动右指针,判断窗口中的元素是否符合条件,不符合条件继续扩充窗口
      2. 缩小窗口,滑动左指针,判断窗口中的元素是否符合条件,符合条件继续缩小窗口

      经过1.和2.不断迭代,最终让左右指针构造的窗口从左往右滑动起来,然后就能取得我们需要的极值

    总的来说,滑动窗口思想还剩很简单的,核心是对于窗口条件扩充和缩小条件的判断

    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author ghp
     * @title 最小覆盖子串
     */
    class Solution {
        public String minWindow(String s, String t) {
            if (s.length() < t.length()) {
                // s的长度小于t,s不可能覆盖t
                return "";
            }
            // map用于判断窗口是否可以缩小
            Map<Character, Integer> map = new HashMap<>();
            for (int k = 0; k < t.length(); k++) {
                char key = t.charAt(k);
                if (map.containsKey(key)) {
                    map.put(t.charAt(k), map.get(key) + 1);
                } else {
                    map.put(t.charAt(k), 1);
                }
            }
            // 存储窗口中的元素
            Map<Character, Integer> contains = new HashMap<>();
            for (int k = 0; k < t.length(); k++) {
                contains.put(t.charAt(k), 0);
            }
            // 左右指针
            int i = 0;
            int j = 0;
            // 记录窗口的最小长度
            int min = Integer.MAX_VALUE;
            // 记录窗口最小长度时的左右边界
            int start = -1;
            // 从做左到右滑动窗口
            while (j < s.length()) {
                if (contains.containsKey(s.charAt(j))) {
                    Character key = s.charAt(j);
                    Integer value = contains.get(key);
                    contains.put(key, value + 1);
                }
                while (isCover(map, contains)) {
                    // 窗口中的元素已经能够覆盖t,缩小窗口
                    if (min > (j - i + 1)) {
                        // 如果当前窗口的长度为最小长度,则更新start和end
                        min = j - i + 1;
                        start = i;
                    }
                    if (contains.containsKey(s.charAt(i))) {
                        // 移除左边界的元素
                        Character key = s.charAt(i);
                        Integer value = contains.get(key);
                        contains.put(key, value - 1);
                    }
                    // 滑动窗口左边界
                    i++;
                }
                // 滑动窗口右边界
                j++;
            }
            // 返回最小窗口长度的字符串(这里要判断start是否是-1,防止索引越界)
            return start == -1 ? "" : s.substring(start, start + min);
        }
    
        private boolean isCover(Map<Character, Integer> map, Map<Character, Integer> contains) {
            // 遍历map,判断当前窗口中的元素是否覆盖t
            for (Character key : map.keySet()) {
                if (map.get(key) > contains.getOrDefault(key, 0)) {
                    // 如果窗口中没有map对应等待元素 或者 窗口中的元素数量不够
                    return false;
                }
            }
            return true;
        }
    }
    

    复杂度分析:

    • 时间复杂度:最好 O ( s . l e n g t h ) O(s.length) O(s.length),最坏 O ( s . l e n g t h ∗ t . l e n g t h ) O(s.length*t.length) O(s.lengtht.length)
    • 空间复杂度: O ( s . l e n g t h + t . l e g n t h ) O(s.length+t.legnth) O(s.length+t.legnth)

    代码优化

    • 时间优化:上面代码比较简单,容易理解,但是每次都需要遍历两边map集合,判断窗口是否符合条件的判断,也需要遍历一遍map集合,耗时比较就,经过提交测试,发现平均耗时高达170ms,排名也比较低。后面我们使用一个count变量来判断当前是否符合条件,从而无需遍历map集合来判别
    • 空间优化:上面代码采用了两个map集合,空间占用较多。所以我们可以单独使用一个数组,这个数组比较讲究,大小刚好是128,09AZa~z 的ASCII刚好是0~128。数组是一种比较简单的数据结构,空间占用较少
    /**
     * @author ghp
     * @title 最小覆盖子串
     */
    class Solution {
        public String minWindow(String s, String t) {
            if (s.length() < t.length()) {
                return "";
            }
            int[] letter = new int[128];
            // 记录t中字符出现的次数
            for (int i = 0; i < t.length(); i++) {
                letter[t.charAt(i)]++;
            }
            int l = 0; // 窗口左边界
            int r = 0; // 窗口左右边界
            int min = Integer.MAX_VALUE; // 记录当前能够覆盖t的最小窗口的长度
            int start = -1; // 记录当前能够覆盖t的最小窗口的长度时的左边界
            int count = t.length();
            while (r < s.length()) {
                char ch = s.charAt(r);
                if (letter[ch] > 0) {
                    // 当前字符被t包含,count--
                    count--;
                }
                // 把右边的字符加入窗口
                letter[ch]--;
                if (count == 0) {
                    // 窗口中的字母已经覆盖t,判断窗口是否需要缩小
                    while (l < r && letter[s.charAt(l)] < 0) {
                        // 左侧元素已经超过了需要的次数,移除左侧元素
                        letter[s.charAt(l)]++;
                        l++;
                    }
                    if (min > r - l + 1) {
                        // 当前窗口中字符的长度为最小的,更新start和min
                        min = r - l + 1;
                        start = l;
                    }
                    // 移除左侧元素使窗口不能够覆盖t,重新开始循环
                    letter[s.charAt(l)]++;
                    l++;
                    count++;
                }
                r++;
            }
            return start == -1 ? "" : s.substring(start, start + min);
        }
    }
    

    经过提交测试,平均耗时只有大约2ms(前面的代码平均耗时170ms),空间占用42MB(前面的代码占用43MB),毫无疑问这次优化是十分值得的(●’◡’●)

    复杂度分析:

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

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

子集

🔒题目

原题链接:78.子集

image-20230616110351693

🔑题解

  • 解法一:BFS

    image-20230616151458725

    import java.util.*;
    
    /**
     * @author ghp
     * @title 最小覆盖子串
     */
    class Solution {
    
        private Deque<Integer> path = new LinkedList<>();
        private Map<Integer, Integer> map;
    
        public List<List<Integer>> subsets(int[] nums) {
            List<List<Integer>> ans = new ArrayList<>();
            ans.add(Collections.emptyList());
            boolean[] vis = new boolean[nums.length];
            bfs(ans, path, vis, nums, 0);
            return ans;
        }
    
        private void bfs(List<List<Integer>> ans, Deque<Integer> path, boolean[] vis, int[] nums, int step) {
            if (path.size() > nums.length) {
                return;
            }
            for (int i = step; i < nums.length; i++) {
                if (!vis[i]) {
                    path.addLast(nums[i]);
                    vis[i] = true;
                    ans.add(new ArrayList<>(path));
                    bfs(ans, path, vis, nums, i);
                    vis[i] = false;
                    path.removeLast();
                }
            }
        }
    }
    

    复杂度分析

    时间复杂度: O ( n ! ) O(n!) O(n!)

    空间复杂度: O ( n ! + n ) O(n!+n) O(n!+n)

    n为nums数组的元素个数

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

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

相关文章

三种方法将Word文档转换为PDF文件格式

如何将Word文档转换为PDF文件格式呢&#xff1f;大家在传输文件时&#xff0c;很多人喜欢使用PDF文件格式&#xff0c;因为它非常稳定&#xff0c;不会出现格式混乱的问题。但有些人可能不知道如何进行转换&#xff0c;今天我将介绍三种转换方法&#xff0c;让我们一起来学习一…

从0开始,精通Go语言Rest微服务架构和开发

说在前面 现在拿到offer超级难&#xff0c;甚至连面试电话&#xff0c;一个都搞不到。 尼恩的技术社区中&#xff08;50&#xff09;&#xff0c;很多小伙伴凭借 “左手云原生右手大数据”的绝活&#xff0c;拿到了offer&#xff0c;并且是非常优质的offer&#xff0c;据说年…

Pytest教程__Hook钩子函数总结(14)

前言 pytest 的钩子函数有很多&#xff0c;通过钩子函数的学习可以了解到pytest在执行用例的每个阶段做什么事情&#xff0c;也方便后续对pytest二次开发学习。 详细文档可以查看pytest官方文档API Reference — pytest documentation 钩子函数总结 第一部分&#xff1a;set…

5、DuiLib组件结构的初探

文章目录 1、DuiLib组件结构的初探 1、DuiLib组件结构的初探 DuiLib 整体的实现不仅仅有控件&#xff0c;还有窗口消息、XML处理等模块&#xff0c;官方曾经过出的一个结构图如下&#xff1a; 图中还是比较详细的描述了 DuiLib 的整体设计&#xff0c;值得注意的部分是 “窗口…

每日一练 | 华为认证真题练习Day61

1、DHCPv6服务器发送的DHCPv6 ADVERTISE报文目的端口号为&#xff1f; A. 548 B. 547 C. 549 D. 546 2、当DHCPv6客户端收到DHCPv6服务器发送的RA报文中的和O标记位取值为下列哪个数值时&#xff0c;DHCPv6客户端采用DHCPv6有状态自动配置获取IPv6地址和其它配置信息&#…

Android libusb库的使用

Download Data Center Software from Total Phase. 1 Aptiv DABR Aptiv acquired Indian Unwired&#xff0c;Delphi Automotive USB Bridge / Hub&#xff0c;Hub中集成了UDC&#xff0c;upstream UDC连接的主机称为A-Host&#xff0c;downstream UDC被B-Host枚举成Relay devi…

一个床垫的故事

这是学习笔记的第 2460篇文章 这是一个床垫的真实故事&#xff0c;想起来还是蛮感慨的&#xff0c;真是太魔幻了。 起因是我哥搬家&#xff0c;有一个很新的品牌床垫&#xff0c;因为新房子那边买家具已经送了一个床垫了&#xff0c;所以就多出来一个床垫&#xff0c;他打算把…

autogpt的使用,还有出现的问题

AutoGPT简介 AutoGPT是一个实验性开源应用程序&#xff0c;展示了GPT-4语言模型的功能。该程序由GPT-4驱动&#xff0c;将LLM“思想”链接在一起&#xff0c;以自主实现您设定的任何目标。作为GPT-4完全自主运行的首批例子之一&#xff0c;AutoGPT突破了人工智能的极限。 注&a…

Opencv-C++笔记 (6) : opencv-图片和视频操作

文章目录 一、读取函数imread二、图片窗口函数namedWindow三、 图片保存Imwrite和显示函数Imshow四、视频数据的读取五、摄像头直接调用 一、读取函数imread cv::Mat cv::imread(const String & filename,int flagsIMREAD_COLOR)filename&#xff1a;需要读取图像的文件名…

Linux运维监控学习笔记4

Zabbix相关的一些概念&#xff1a; Zabbix用户和用户群组&#xff1a; 用户&#xff1a;Zabbix提供多用户管理&#xff0c;不同的用户可以设置不同的权限&#xff0c;不同的语言和不同的报警方式。 1&#xff09;创建用户&#xff1a;点击“创建用户”按钮&#xff1a; 2&…

NOTA PEG7 Azide,NOTA-七聚乙二醇叠氮,新型双功能整合剂

NOTA PEG7 Azide中NOTA及其衍生物是新型双功能整合剂之一。NOTA及其衍生物具有良好的配位和鳌合能力&#xff0c;可作为过渡金属离子的配体。叠氮化物基团可以参与铜催化的与炔部分的点击化学反应。 聚乙二醇在科研领域运用广泛&#xff0c;聚乙二醇具有良好的水溶性&#xff0…

【FPGA入门】第一篇、Verilog基本语法常识

目录 第一部分、不同的变量类型 1、wire和reg的区别 2、如何对变量进行赋值呢&#xff1f; 3、什么是阻塞&#xff1f;什么是非阻塞&#xff1f; 第二部分、变量位宽的定义 1、各种系统默认情况 2、变量位宽声明方式 3、表明位宽的情况下&#xff0c;赋值方式 4、两个模…

来自一个敲了5年代码的网络安全工程师的自述(目前薪资30K)

本人是一名敲了5年半代码的网络安全工程师&#xff0c;目前在杭州工作&#xff0c;月薪目前是在30.6K左右&#xff0c;经历过两次跳槽&#xff0c;第一次跳槽拿到了12K的offer&#xff0c;第二次跳槽拿到18K的offer。一直到目前为止的30K左右。 说到这里再给大家提个醒&#x…

SpringBoot整合定时任务技术Quartz

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ RequestMapping注解 &#x1f680;Quartz应用场…

好消息!PMP证书还没过期的宝子,可以增持免考CSPM-2证书

2021年10月&#xff0c;中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系&#xff0c;开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会&#xff08;CAS&#xff09;组织开展的项…

如何使用hexo next主题,新建一个专栏

文章目录 backgroundIntroHow to do that&#xff1f;&#x1f388; background 今天突发奇想&#xff0c;想要在自己的博客中增加一个新的专栏&#xff0c;记录自己的一些随想。起因是不想让博客成为一个纯粹记录技术成长的网站&#xff0c;&#xff08;毕竟如果真的有人要看…

PostgreSQL(八)锁的相关操作

目录 一、锁存在的意义二、表级锁1.ACCESS SHARE2.ROW SHARE3.ROW EXCLUSIVE4.SHARE UPDATE EXCLUSIVE5.SHARE6.SHARE ROW EXCLUSIVE7.EXCLUSIVE8.ACCESS EXCLUSIVE9.表级锁模式冲突表10.示例一11.示例二 三、行级锁1.FOR UPDATE2.FOR NO KEY UPDATE3.FOR SHARE4.FOR KEY SHARE…

那个准点下班的人,比我先升职了...

前言 二黑最近心态很崩。 和他同期一道进公司的陈琪又升了一级&#xff0c;可是明明大家在进公司时&#xff0c;喜子不论是学历还是工作经验&#xff0c;样样都不如自己&#xff0c;眼下不过短短的两年时间便一跃在自己的职级之上&#xff0c;这着实让他有几分不甘心。 二黑…

Unity 安装负责音频的 wwise

很多游戏的音频用的是 wwise 先下载 https://www.audiokinetic.com/zh/download 安装的时候要选sdk 就是20g的那个 然后运行 选择unity 可以看到这个界面 好&#xff0c;现在开始要安装离线包 直接项目里点 第二个 装好后 他会提示你 无法找到unity安装的地址 1 打开你的 …

干货 | 电路中为何需要串联小电阻?

电路中串联小电阻是电路设计中常见的一种技术手段&#xff0c;它可以在电路中起到多种作用。在本文中&#xff0c;我将从不同的角度分析串联小电阻的作用&#xff0c;深入探讨为何需要在电路中串联小电阻。 一、串联小电阻的概念和作用 串联小电阻是指在电路中串联一个电阻&am…