LeetCode - Google 校招100题 第7天 序列(数据结构贪心) (15题)

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/144744418

Stack
相关文章:

LeetCode 合计最常见的 112 题:

  1. 校招100题 第1天 链表(List) (19题)
  2. 校招100题 第2天 树(Tree) (21题)
  3. 校招100题 第3天 动态规划(DP) (20题)
  4. 校招100题 第4天 查找排序(Search&Sort) (16题)
  5. 校招100题 第5天 双指针(Two Pointers) (11题)
  6. 校招100题 第6天 回溯法(Backtracking) (8题)
  7. 校招100题 第7天 序列(数据结构&贪心) (15题)
  8. 校招100题 第8天 图(Graph) (2题)

序列(数据结构&贪心) 算法包括栈、字典、集合、贪心等,基于不同的数据存储和访问方式的数据结构。栈(Stack) 是一种 后进先出(LIFO) 的数据结构,支持 推入(append) 和 弹出(pop) 操作,常用于处理嵌套问题和回溯算法。字典(Map) 是一种基于键值对的存储结构,提供快速的查找、插入和删除操作,其效率通常与哈希表的实现有关。集合(Set) 是一种无序且元素唯一的数据结构,支持高效的成员检查、添加和删除操作,常用于去重和数学集合操作。

题目(15题):

  1. 栈:20. 有效的括号 (Easy)、32. 最长有效括号 (Hard)、394. 字符串解码、739. 每日温度 (单调栈)
  2. 集合:128. 最长连续序列
  3. 字典:49. 字母异位词分组、560. 和为 K 的子数组 (前缀树字典)
  4. 贪心:55. 跳跃游戏、45. 跳跃游戏 II、134. 加油站、121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II
  5. 矩阵模拟:48. 旋转图像、54. 螺旋矩阵、59. 螺旋矩阵 II

1. 栈

1.1 20. 有效的括号 (Easy)

class Solution:
    def isValid(self, s: str) -> bool:
        """
        有效括号,()[]{},时间O(N),空间O(N)
        """
        stack = []
        pair_list = [['(', ')'], ['{', '}'], ['[', ']']]
        for c in list(s):
            if c in ['(', '{', '[']:
                stack.append(c)
                continue
            if not stack:
                return False
            for p in pair_list:
                if c == p[1]:
                    if stack.pop() != p[0]:
                        return False
        return True if not stack else False

1.2 32. 最长有效括号 (Hard)

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        """
        最长有效括号, stack+flags更清晰,格式正确且连续,时间O(n), 空间O(n)
        """
        n = len(s)
        flags = [False] * n # dp
        stack = []  # 使用stack保存索引值
        for i in range(n):
            if s[i]=='(':
                stack.append(i)
            else:
                if stack:
                    j = stack.pop(-1)
                    flags[i], flags[j] = True, True # 匹配成功时标记   
        val, res = 0, 0
        for flag in flags:    # 计算连续1出现的最大次数
            if flag:
                val += 1
            else:          #遇到0时中断,进行对比,并重置
                res = max(res, val)  
                val = 0
        res = max(res, val) #最后一次统计可能未终断,多做一次对比
        return res

1.3 394. 字符串解码

class Solution:
    def decodeString(self, s: str) -> str:
        """
        栈操作,类似3[a]2[bc],时间O(S+|s|),空间复杂度O(S)
        """
        stack = []
        res = ""
        for c in s:
            if c != "]":  # 不等于
                stack.append(c)
            else:  # 解码"]"
                tmp = ""
                while stack[-1] != "[":
                    item = stack.pop()
                    tmp += item[::-1]  # 内部需要翻转,防止嵌套括号
                tmp = tmp[::-1]  # 整体进行翻转
                stack.pop()
                times = ""
                while stack and stack[-1].isdigit():
                    times += stack.pop()
                tmp = tmp * int(times[::-1])
                stack.append(tmp)
        res = "".join(stack)
        return res

1.4 739. 每日温度

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        """
        最高温度出现在第几天之后,输入列表,返回列表。
        单调栈,当前大于栈内最大值,则更新结果之后出栈
        时间O(n),空间O(n)
        """
        n = len(temperatures)
        stack = []  # 单调栈
        res = [0] * n
        for i in range(n):
            while stack and temperatures[i] > temperatures[stack[-1]]:
                res[stack[-1]] = i - stack[-1]
                stack.pop()
            stack.append(i)
        return res

2. 集合

2.1 128. 最长连续序列

class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        """
        最长连续序列,不考虑顺序,只考虑是否+1(连续),哈希表,依次判断是否存在,
        时间O(N),空间O(N)
        """
        res = 0
        n_set = set(nums)
        for num in n_set:
            if (num - 1) not in n_set:  # 避免重复计算
                tmp = 1  # 连续值
                val = num
                while (val+1) in n_set:
                    tmp += 1
                    val += 1
                res = max(res, tmp)
        return res

3. 字典

3.1 49. 字母异位词分组

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        """
        排序key的字典,时间O(n*klogk), 空间(nk)
        """
        mp = collections.defaultdict(list)
        for s in strs:
            x = "".join(sorted(s))
            mp[x].append(s) # 组成字典
            
        res = []
        for k in mp.keys():
            res.append(mp[k])  # 添加原始数据
        return res

3.2 560. 和为 K 的子数组 (前缀和PreSum)

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        """
        前缀和 + 哈希表优化: pre[i]-pre[j-1]=k -> pre[j-1]=pre[i]-k
        pre[i]是前n项的和, pre[j-1]是之前出现的和,统计哈希表中pre[j-1]出现的次数,即可。
        时间复杂度O(N), 空间O(N)
        """
        n = len(nums)
        presum = 0  # presum[i],前缀值
        res = 0
        mp = collections.defaultdict(int) # 统计前缀值出现的次数
        mp[0] = 1 # 注意,初始化前缀值0是1
        for i in range(n):
            presum += nums[i]
            tmp = presum - k  # pre[j-1]的值
            if tmp in mp.keys():  # 这个值出现过,加入这个值出现的次数
                res += mp[tmp]
            mp[presum] += 1  # 加入新值
        return res

4. 贪心

4.1 55. 跳跃游戏

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        """
        跳跃游戏1,是否成功,贪心,最大跳跃长度,超越数组,时间O(n),空间O(1)
        """
        n = len(nums)
        max_v = 0  # 到达的最远距离
        for i in range(n):
            if i <= max_v:  # 判断当前点能否到达
                max_v = max(max_v, nums[i]+i) # nums[i]+i 跳跃的最大长度
                if max_v >= n-1:  # 大于最后一个位置
                    return True
            else:
                break
        return False

4.2 45. 跳跃游戏 II

class Solution:
    def jump(self, nums: List[int]) -> int:
        """
        跳跃游戏2,最小跳跃次数,贪心,时间O(n),空间O(1)
        """
        n = len(nums)
        max_v = 0  # 到达的最远距离
        res, max_end = 0, 0
        for i in range(n-1):
            if i <= max_v:  # 小于一次最远位置
                max_v = max(max_v, nums[i]+i)  # 当前最远的位置
                if i == max_end:  # i到达边界步数
                    max_end = max_v  # 更新最大边界,同时跳跃次数+1
                    res+=1  # 步数+1,一次一次的更新
        return res

4.3 134. 加油站

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        """
        运行环路一周,贪心算法,gas是加油数量,cost是花费,选择起始位置
        燃料最低点的下一个开始,时间O(n), 空间O(1)
        """
        n = len(gas)
        val = 0
        min_v= float("inf")
        min_i = 0  # 燃料最低点的位置
        for i in range(n):
            val += gas[i] - cost[i]  # 累计剩余燃料
            if val <= min_v:  # 保存剩余燃料最低值
                min_v = val
                min_i = i
        if val < 0:
            return -1
        return (min_i+1) % n  # 最低燃料的下一个开始

4.4 121. 买卖股票的最佳时机

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        """
        买卖股票1,只在一只赚钱,时间O(n),空间O(1)
        """
        prev = prices[0]
        res = 0
        n = len(prices)
        for i in range(n):
            res = max(res, prices[i]-prev)
            prev = min(prev, prices[i])
        return res

4.5 122. 买卖股票的最佳时机 II

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        """
        买卖股票2,赚差价,贪心,累加区间最大值,时间O(n),空间O(1)
        """
        n = len(prices)
        res=0
        for i in range(1, n):
            res + = max(0, prices[i]-prices[i-1])
        return res

5. 矩阵模拟

5.1 48. 旋转图像

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        水平翻转(上下翻转)、对角线翻转,即是旋转图像
        时间O(n^2),空间O(1)
        """
        if not matrix or not matrix[0]:
            return
        m = len(matrix)
        n = len(matrix[0])
        # 水平翻转
        for i in range(m//2):
            for j in range(n):
                matrix[i][j], matrix[m-i-1][j] = matrix[m-i-1][j], matrix[i][j]
        # 对角矩阵翻转
        for i in range(m):
            for j in range(i):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

5.2 54. 螺旋矩阵

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:        
        """
        4个指针 + 上右不用判断,下左需要判断边界,时间O(mn), 空间O(1), 空间排除输出之外的复杂度
        """
        if not matrix or not matrix[0]:
            return []
        m = len(matrix)
        n = len(matrix[0])
        res = []
        left, right, top, bottom = 0, n-1, 0, m-1
        while left <= right and top <= bottom:
            for i in range(left, right+1):
                res.append(matrix[top][i])
            for i in range(top+1, bottom+1):
                res.append(matrix[i][right])
            # 非常重要的边界判断,否则会重复
            if left < right and top < bottom:
                for i in range(right-1, left-1, -1):
                    res.append(matrix[bottom][i])
                for i in range(bottom-1, top, -1):
                    res.append(matrix[i][left])
            left += 1
            right -= 1
            top += 1
            bottom -= 1
        return res

5.3 59. 螺旋矩阵 II

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        """
        螺旋矩阵2,生成矩阵
        与 剑指 Offer 29. 顺时针打印矩阵 类似,注意:
        外层是while left <= right and top <= bottom,有等于
        内层是if left < right and top < bottom,没有等于
        时间复杂度是O(n^2),空间是O(1)
        """
        left, right = 0, n-1
        top, bottom = 0, n-1
        matrix = [[0] * n for _ in range(n)]
        num = 0
        while left <= right and top <= bottom:
            for i in range(left, right+1):
                num += 1
                matrix[top][i] = num
            for i in range(top+1, bottom+1):
                num += 1
                matrix[i][right] = num
            if left < right and top < bottom:
                for i in range(right-1, left-1, -1):
                    num += 1
                    matrix[bottom][i] = num
                for i in range(bottom-1, top, -1):
                    num += 1
                    matrix[i][left] = num
            left += 1
            right -= 1
            top += 1
            bottom -= 1
        return matrix

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《Java核心技术 卷II》流的创建

流的创建 Collection接口中stream方法可以将任何集合转换为一个流。 用静态Stream.of转化成数组。 Stream words Stream.of(contents.split("\\PL")); of方法具有可变长参数&#xff0c;可以构建具有任意数量的流。 使用Array.stream(array,from,to)可以用数组…

应用层协议(Https)(超详解)

前言&#xff1a; https是在http基础上的进行一些"加密"操作&#xff0c;也可以认为是http的强化版。 在下面展开对https的讨论中&#xff0c;可能不会再涉及到http的相关协议&#xff0c;如有对http的疑惑或是其他不一样的看法可以浏览上一篇文章&#xff1a;应用层…

ESP32 I2S音频总线学习笔记(一):初识I2S通信与配置基础

文章目录 简介为什么需要I2S&#xff1f;关于音频信号采样率分辨率音频声道 怎样使用I2S传输音频&#xff1f;位时钟BCLK字时钟WS串行数据SD I2S传输模型I2S通信格式I2S格式左对齐格式右对齐格式 i2s基本配置i2s 底层API加载I2S驱动设置I2S使用的引脚I2S读取数据I2S发送数据卸载…

优化租赁小程序提升服务效率与用户体验的策略与实践

内容概要 在这个快速发展的商业环境中&#xff0c;租赁小程序成为了提升服务效率和用户体验的重要工具。通过对用户需求的深入挖掘&#xff0c;我们发现他们对于功能的便捷性、响应速度和界面的友好性有着极高的期待。因此&#xff0c;针对这些需求&#xff0c;完善租赁小程序…

HTML——13.超链接

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>超链接</title></head><body><!--超链接:从一个网页链接到另一个网页--><!--语法&#xff1a;<a href"淘宝网链接的地址"> 淘宝…

day-102 二进制矩阵中的最短路径

思路 BFS 解题过程 从起点依次向八个方向尝试&#xff08;之后也一样&#xff09;&#xff0c;如果某个位置在矩阵内且值为0且没有访问过&#xff0c;将其添加到一个队列中&#xff0c;依次类推&#xff0c;直到到达出口 Code class Solution {public int shortestPathBinar…

王佩丰24节Excel学习笔记——第十八讲:Lookup和数组

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 地址栏公式可以使用 F9 查看&#xff0c;取消请按Esc键&#xff0c;或者公式前的红色叉&#xff1b;使用数组时一定要注意使用绝对引用&#xff0c;方便下拉&#xff1b;使用数组时一…

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成Log4j1.x 及 原理分析

文章目录 Pre官网集成Log4j1.x步骤POM依赖使用第一步&#xff1a;编写 Log4j 配置文件第二步&#xff1a;代码 原理分析1. 获取对应的 ILoggerFactory2. 根据 ILoggerFactory 获取 Logger 实例3. 日志记录过程 小结 Pre Java - 日志体系_Apache Commons Logging&#xff08;JC…

嵌入式开发中的机器人表情绘制

机器人的表情有两种&#xff0c;一种是贴图&#xff0c;一钟是调用图形API自绘。 贴图效果相对比较好&#xff0c;在存储空间大的情况下是可以采用的。 自绘比较麻烦&#xff0c;但在资源和空缺少的情况下&#xff0c;也是很有用的。而且自绘很容易通过调整参数加入随机效果&…

LLM高性能并行训练技术

LLM高性能并行训练技术 研究背景与意义 深度学习的重要性:人工智能成为国际竞争焦点,深度学习是其核心技术,在众多领域取得突破,推动社会向智能化跃升。面临的挑战:数据、模型规模呈指数级增长,硬件算力发展滞后。单个 GPU 难以满足大规模模型训练需求,分布式训练面临通…

Docker镜像瘦身:从1.43G到22.4MB

Docker镜像瘦身:从1.43G到22.4MB 背景1、创建项目2、构建第一个镜像3、修改基础镜像4、多级构建5、使用Nginx背景 在使用 Docker 时,镜像大小至关重要。我们从 create-react-app (https://reactjs.org/docs/create-a-new-react-app.html)获得的样板项目通常都超过 1.43 GB…

【电路理论四】正弦电流电路

正弦电流 正弦量是随时间按正弦规律变动的电路变量。 随时间按正弦规律变动的电流称为正弦电流。 正弦电流的瞬时值表达式&#xff1a; 称为正弦电流的三要素。 分别为振幅/幅值&#xff0c;角频率&#xff0c;初相。 幅值为正弦电流的最大值&#xff0c;恒为正。 为正弦电…

深度学习使用Anaconda打开Jupyter Notebook编码

新手入门深度学习使用Anaconda打开Jupyter Notebook编码 1. 安装Anaconda 第一种是Anaconda官网下载安装包&#xff0c;但是很慢&#xff0c;不太建议 第二种使用国内清华大学镜像源下载 选择适合自己电脑的版本&#xff0c;支持windows&#xff0c;linux系统 下载完之后自行…

【MySQL】搞懂mvcc、read view:MySQL事务原理深度剖析

前言&#xff1a;本节内容是事务里面最难的一部分&#xff0c; 就是理解mvcc快照读和read view。这两个部分需要了解隔离性里面的四种隔离级别。 博主之前讲过&#xff0c;但是担心友友们不了解&#xff0c; 所以这里开头进行了复习。 下面开始我们的学习吧&#xff01; ps&…

VITUREMEIG | AR眼镜 算力增程

根据IDC发布的《2024年第三季度美国AR/VR市场报告》显示&#xff0c;美国市场AR/VR总出货量增长10.3%。其中&#xff0c;成立于2021年的VITURE增长速度令人惊艳&#xff0c;同比暴涨452.6%&#xff0c;成为历史上增长最快的AR/VR品牌。并在美国AR领域占据了超过50%的市场份额&a…

cuda-cuDnn

cuda sudo /bin/sh cuda_11.7.0_515.43.04_linux.run cudnn cuDNN Archive | NVIDIA Developer Linux 系统 CUDA 多版本共存以及切换 – 颢天 安装cuda # 如果已经安装过驱动&#xff0c;驱动不需要再安装&#xff0c;取消勾选 安装cuDNN&#xff0c;cuda-cuDNN对应关系见…

# 【鸿蒙开发】多线程之Worker的使用

【鸿蒙开发】多线程之Worker的使用 文章目录 【鸿蒙开发】多线程之Worker的使用前言一、Worker的介绍二、注意事项三、Worker使用示例1.新建一个Worker2.主线程使用Worker3.子线程Worker的使用 四、效果展示 前言 本文主要介绍了多线程的方法之一&#xff0c;使用Worker开启多…

Spring Cloud由入门到精通

文章目录 1.初识微服务1.1. 单体架构1.2.分布式架构1.3.微服务1.4 微服务技术比对1.5.Spring Cloud1.6. 总结2.服务拆分和远程调用2.1.服务拆分原则2.2.服务拆分示例2.2.1.项目工程结构设计2.2.2.创建Maven项目工程2.3.实现远程调用案例2.3.1.案例需求:2.3.2. 注册 Rest Templ…

电脑缺失libcurl.dll怎么解决?详解电脑libcurl.dll文件丢失问题

一、libcurl.dll文件丢失的原因 libcurl.dll是一个用于处理URL传输的库文件&#xff0c;广泛应用于各种基于网络的应用程序。当这个文件丢失时&#xff0c;可能会导致相关应用程序无法正常运行。以下是libcurl.dll文件丢失的一些常见原因&#xff1a; 软件安装或卸载不完整&a…

XIAO Esp32S3 播放网络Mp3

本文旨在使用XIAO Esp32S3 播放网络Mp3 所需硬件 max98357 接线 Xiao Esp32 S3Max983574LRC5BCLK 6DIN5VVinGNDGND代码: #include "Arduino.h" #include "WiFiMulti.h" #include "Audio.h"// Digital I/O used #def