LeetCode热题HOT100:单词拆分、环形链表 II、LRU 缓存

news2024/11/20 20:25:57

LeetCode热题HOT100

139. 单词拆分

题目:给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。

思路分析: 使用一个布尔数组 dp[],大小为 s.length() + 1,其中 dp[i] 表示我们是否可以使用字典中的单词从索引0到索引i-1拆分字符串s。基本情况是 dp[0] = true,因为空字符串总是可以被拆分。然后,我们从左到右遍历字符串 s,对于每个索引 i,我们遍历所有可能的分割点 j,使得 0 <= j < i。如果 dp[j] 为 true,这意味着我们可以从0到j-1拆分字符串,且从j到i-1的子字符串在字典中,则我们可以从0到i-1拆分字符串。我们将 dp[i] 设置为true,并退出内部循环。最后,我们返回 dp[s.length()],它表示我们是否可以使用字典中的单词拆分整个字符串。

class Solution {
        // 定义一个方法,用于判断给定的字符串 s 是否可以被拆分成字典中的单词
        public boolean wordBreak(String s, List<String> wordDict) {
            // 定义一个布尔类型的数组 dp,长度为 s.length() + 1
            boolean[] dp = new boolean[s.length() + 1];
            // 将 dp[0] 设为 true,因为空字符串总是可以被拆分
            dp[0] = true;
            // 从 1 到 s.length() 遍历每个字符串
            for (int i = 1; i <= s.length(); i++) {
                // 从 0 到 i 遍历每个可能的拆分点
                for (int j = 0; j < i; j++) {
                    // 如果 dp[j] 为 true,意味着 s 的前半部分可以被拆分成字典中的单词,且 s 的后半部分也在字典中,则将 dp[i] 设为 true
                    if (dp[j] && wordDict.contains(s.substring(j, i))) {
                        dp[i] = true;
                        break;
                    }
                }
            }
            // 返回 dp[s.length()],表示 s 是否可以被拆分成字典中的单词
            return dp[s.length()];
        }
    }

142. 环形链表 II

题目:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定
链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表
**示例 1:在这里插入图片描述
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

思路分析: 使用快慢指针,快指针每次走两步,慢指针每次走一步,如果链表存在环,那么快慢指针一定会相遇。在相遇时,我们可以通过计算快指针和慢指针走过的节点数来确定环中节点的个数。然后,将快指针重新指向头节点,让其先走 n 步,再让快慢指针同时走,相遇的节点即为环的入口节点。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) { // 如果链表为空,则直接返回 null
            return null;
        }

        ListNode fast = head; // 定义快指针,指向链表头
        ListNode slow = head; // 定义慢指针,指向链表头
        boolean flag = false; // 定义标志位,判断链表是否存在环

        // 使用快慢指针判断链表是否存在环
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) { // 如果快慢指针相遇,则说明链表存在环
                flag = true; // 将标志位设为 true
                break;
            }
        }

        if (!flag) { // 如果标志位为 false,则说明链表不存在环,直接返回 null
            return null;
        } else { // 如果标志位为 true,则说明链表存在环
            int n = 1; // 定义计数器,记录环中节点的个数
            fast = fast.next;
            while (fast != slow) { // 统计环中节点的个数
                n++;
                fast = fast.next;
            }

            fast = head; // 将快指针重新指向头节点
            slow = head; // 将慢指针重新指向头节点
            for (int i = 0; i < n; i++) { // 让快指针先走 n 步
                fast = fast.next;
            }

            // 快慢指针同时走,相遇的节点即为环的入口节点
            while (fast != slow) {
                fast = fast.next;
                slow = slow.next;
            }

            return fast; // 返回环的入口节点
        }
    }
}

146. LRU 缓存

题目:请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;
如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,
则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
**示例 1:
输入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

思路分析: 使用双向链表和哈希表来实现LRU缓存。在双向链表中,每个节点保存了该节点的键值对,并且维护了前驱和后继指针。在哈希表中,每个键都映射到对应的节点。当访问一个键时,如果哈希表中包含该键,则将该节点移动到链表头部,并返回节点的值;如果哈希表中不包含该键,则返回-1。在插入一个键值对时,如果哈希表中不包含该键,则创建一个新节点并将其添加到链表头部和哈希表中;如果哈希表中包含该键,则删除旧节点,创建一个新节点并将其添加到链表头部和哈希表中。当缓存达到容量限制时,删除链表最后一个节点和哈希表中对应的项。

class LRUCache {
    // 双向链表和哈希表
    DoubleLinkedList doubleLinkedList;
    HashMap<Integer, Node> map;
    // 缓存最大容量
    int capacity;

    public LRUCache(int capacity) {
        // 初始化双向链表和哈希表
        doubleLinkedList = new DoubleLinkedList();
        map = new HashMap<>();
        // 初始化缓存最大容量
        this.capacity = capacity;
    }

    public int get(int key) {
        // 如果哈希表中不包含该键,则返回-1
        if (!map.containsKey(key)) {
            return -1;
        } else {
            // 如果哈希表中包含该键,则将该节点移动到链表头部,并返回节点的值
            Node cur = map.get(key);
            doubleLinkedList.delete(cur);
            doubleLinkedList.addFirst(cur);
            return cur.val;
        }
    }

    public void put(int key, int value) {
        // 创建新节点
        Node newNode = new Node(key, value);
        if (!map.containsKey(key)) {
            // 如果哈希表中不包含该键,则将新节点添加到链表头部和哈希表中
            if (map.size() == capacity) {
                // 如果缓存已满,则删除链表最后一个节点和哈希表中对应的项
                int k = doubleLinkedList.deleteLast();
                map.remove(k);
            }
            doubleLinkedList.addFirst(newNode);
            map.put(key, newNode);
        } else {
            // 如果哈希表中包含该键,则删除旧节点,将新节点添加到链表头部和哈希表中
            doubleLinkedList.delete(map.get(key));
            doubleLinkedList.addFirst(newNode);
            map.put(key, newNode);
        }
    }
}

class Node {
    // 节点键和值
    int key;
    int val;
    // 节点的前驱和后继
    Node pre;
    Node next;

    public Node(int key, int val) {
        // 初始化节点
        this.key = key;
        this.val = val;
    }
}

class DoubleLinkedList {
    // 双向链表的头节点和尾节点
    Node head;
    Node tail;

    public DoubleLinkedList() {
        // 初始化双向链表
        head = new Node(-1, -1);
        tail = new Node(-1, -1);
        head.next = tail;
        tail.pre = head;
    }

    public void addFirst(Node node) {
        // 将节点添加到链表头部
        node.next = head.next;
        node.pre = head;
        head.next.pre = node;
        head.next = node;
    }

    public int delete(Node node) {
        // 删除指定节点
        node.pre.next = node.next;
        node.next.pre = node.pre;
        return node.key;
    }

    public int deleteLast() {
        // 删除链表最后一个节点
        return delete(tail.pre);
    }
}

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

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

相关文章

[前端基础]Node.js简单操作,手把手教你搭建一个轻量级应答服务器(会继续补充操作细节,欢迎讨论)

注意:前置知识:回调函数,异步,ajax技术,端口 目录 1.什么是node.js 2.模块的概念 3. 回调函数 4.关于文件的管理 5.关于流的操作 6.关于构建服务器:前端部分,如何向后端发送请求 7.后端创建简单的服务器对象 8.后端如何处理请求 9.前端如何处理返回的数据 10.简易应答…

STL标准模板库 vector容器与迭代器入门

STL五大件 标准模板库vector容器&#xff1a;vector 声明初始化vector 容器 &#xff1a;push_backvector 容器 &#xff1a;push_back的问题vector容器&#xff1a;push_back的问题&#xff0c;reserve解决 vector容器&#xff1a;insert函数vector容器&#xff1a;insert函数…

【从零开始玩量化17】如何python+QMT完成自动化交易?(全网最详细入门教程)

一、什么是QMT 此部分为扫盲内容&#xff0c;有一定了解者可以跳过。 概念 它是一款量化交易客户端软件&#xff0c;由一家叫做迅投公司出品&#xff0c;可以直接登录你的券商账号进行股票交易&#xff0c;但与同花顺/通信达不同的是&#xff0c;它暴露了基于python的交易API&…

【人生苦短,我学 Python】进阶篇——异常处理(Day16)

写在前面&#xff1a;大家好&#xff01;我是【AI 菌】。我热爱AI、热爱分享、热爱开源&#xff01; 这博客是我对学习的一点总结与记录。如果您也对 深度学习、机器视觉、算法、Python、C 感兴趣&#xff0c;可以关注我的动态&#xff0c;我们一起学习&#xff0c;一起进步~ 我…

Python小姿势 - 可选知识点:

可选知识点&#xff1a; 列表推导式 列表和字典推导式 字典推导式 生成器表达式 带条件的生成器表达式 解析XML 解析JSON 使用Requests和BeautifulSoup爬虫 Python并发编程 Python多线程编程 Python多进程编程 Python异步编程 Python装饰器 Python闭包 Python模块化 Python类和…

PM510V16 3BSE008358R1嵌入式卡件用于励磁系统多用于工业发电

​ PM510V16 3BSE008358R1嵌入式卡件用于励磁系统多用于工业发电 物联网与工业自动化控制系统的联系 当今&#xff0c;物联网可谓是在各大媒体出镜率最高、而且与“智能”联系密切的名词之一。从“管理、控制、智能”的角度来看&#xff0c;其实物联网与工业自动化是一脉相承的…

Kafka技术基础

Apache Kafka发源于LinkedIn&#xff0c;于2011年成为Apache的孵化项目&#xff0c;随后于2012年成为Apache的主要项目之一&#xff0c;是消息队列的一种实现方式&#xff0c;提供消息的持久化。Kafka使用Scala和Java进行编写。Apache Kafka是一个快速、可扩展的、高吞吐、可容…

IEEE-TMI:张孝勇团队开发小鼠精细脑结构自动分割的深度学习算法

近日&#xff0c;复旦大学类脑智能科学与技术研究院青年研究员张孝勇课题组联合德国亥姆霍兹慕尼黑研究中心&#xff0c;在医学图像处理领域顶尖期刊《IEEE医学影像汇刊》(IEEE Transactions on Medical Imaging&#xff0c;TMI) 发表了题为《MouseGAN&#xff1a;用于小鼠大脑…

OpenCV 模板匹配 matchTemplate

一、模板匹配概念 模板匹配是一项在一副图像中寻找与另一幅模板图像最匹配&#xff08;相似&#xff09;部分的技术。模板匹配不是基于直方图的&#xff0c;而是通过在输入图像上滑动图像块&#xff08;模板&#xff09;同时对比相似度&#xff0c;来对模板和输入图像进行匹配的…

【IoT】如何使用软件加密(文件夹加密工具.exe),并破解工具

目录 第一步&#xff1a;显示隐藏的文件。 第二步&#xff1a;将隐藏文件变成文件夹。 第三步&#xff1a;解密文件。 有时候出差或者有些商务场合&#xff0c;需要对一些敏感文件做一下简单的加密&#xff0c;这样在分享内容的时候&#xff0c;可以起到初步的保护作用。 当…

Windows利用easyBCD装Ubuntu双系统

一、准备材料&#xff1a; 1、easyBCD软件&#xff08;我用V2.3版本&#xff09; 2、Ubuntu系统&#xff08;我用的12.04版本ubuntu-12.04-desktop-i386.iso&#xff09; 二、配置空闲分区 1、右击“计算机”--->管理--->右击某个自己分配的分区--->选择“压缩卷”…

Deep Bidirectional Language-Knowledge Graph Pretraining论文阅读

Deep Bidirectional Language-Knowledge Graph Pretraining github代码 摘要 最近的工作表明&#xff0c;知识图(KG)可以补充文本数据&#xff0c;提供结构化的背景知识&#xff0c; 为推理提供有用的支架。然而&#xff0c;这些作品并没有经过预先的训练来学习大规模的两种…

央视推荐的护眼灯是哪款?盘点央视推荐的护眼灯排名

护眼灯是生活中最常见的照明工具&#xff0c;许多人担心品质不过关 不合格的护眼灯会造成视损害 建议在选购护眼灯时&#xff1a; 首先看清楚产品的具体标识&#xff0c;其中就包括有产品的生产厂家&#xff0c;生产地址以及他们的产品型号 看产品规格和是否获得了国家的相关…

博睿数据蝉联中国APM市场份额第一,Bonree ONE春季正式版重磅发布

日前&#xff0c;IDC发布《中国IT统一运维软件产品市场跟踪报告&#xff0c;2022H2》,2022下半年中国APM市场环比增长近10%。博睿数据以市场份额达18.28%蝉联APM应用性能监控市场份额第一。 追求卓越&#xff0c;顺势而为 博睿数据作为中国领先的一体化智能可观测平台&#xf…

今天主要谈谈关于申请美国专利的一些问题

进入2021年&#xff0c;国家更多的开始鼓励在国外开展业务的企业去布局国外专利&#xff0c;提升企业海外竞争力。无他&#xff0c;着实是我们在知识产权保护方面起步太晚&#xff0c;已经吃亏了太久&#xff0c;专利掣肘&#xff0c;技术卡脖子&#xff0c;勤勉的为别人打工。…

Domino自带的JSON校验工具

大家好&#xff0c;才是真的好。 JSON数据在Notes/Domino已经变得非常重要。从Domino 10开始&#xff0c;在LotusScript语言中就加入了对JSON数据处理功能。在管理中&#xff0c;我们知道&#xff0c;从Domino 12版本开始就支持Domino自动化配置&#xff0c;也是使用JSON数据作…

利用ESP32-C3实现一个风扇PWM控制器,可网页操作

1简介 这段代码是一个基于ESP32开发板的PWM控制器&#xff0c;可以通过网页输入控制参数并显示在屏幕上&#xff0c;通过PWM输出引脚控制风扇的转速&#xff0c;还可以测量风扇的转速并在屏幕上显示。此外&#xff0c;代码还具备显示当前时间、显示Wi-Fi连接信息等功能。 2函数…

【Git基础】常用git命令(三)

文章目录 1.版本回退1.1 没有commit的情况1.2 已经commit但没有push的情况1.3 已经push到远端仓库的情况 2. 删除文件2.1 从工作区删除文件2.2 使用git rm命令删除文件2.3 永久删除文件2.4 永久删除文件的步骤拆解 3. 查看指定文件的修改3.1 查看文件的所有commit3.2 查看所有c…

亚控组态王与EXCEL通信

先创建一个IO设备&#xff1a;DDE类型 创建一个变量&#xff1a; 创建一个窗口&#xff0c;建立一个文本显示并关联前面建立的变量 先打开一个EXCEL文件&#xff08;注意&#xff1a;WPS是不兼容的&#xff0c;必须先打开EXCEL文件&#xff0c;否则会报错&#xff09; …

云原生|kubernetes|rancher-2.6.4安装部署简明手册

前言: rancher是一个比较特殊的开源的kubernetes管理工具&#xff0c;特殊在它是一个名称为k3s的简单kubernetes集群&#xff0c;而该集群是在kubernetes集群内的。 OK&#xff0c;本文将讲述如何在centos7服务器上&#xff0c;在已有的kubernetes-1.23.15集群内&#xff0c;…