Leetcode 剑指 Offer II 009. 乘积小于 K 的子数组

news2024/10/5 14:37:15

题目难度: 中等

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

  • 给定一个正整数数组 nums 和整数 k ,请找出该数组内乘积小于 k 的连续的子数组的个数。

示例 1:

  • 输入: nums = [10,5,2,6], k = 100
  • 输出: 8
  • 解释: 8 个乘积小于 100 的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。
  • 需要注意的是 [10,5,2] 并不是乘积小于 100 的子数组。

示例 2:

  • 输入: nums = [1,2,3], k = 0
  • 输出: 0

提示:

  • 1 <= nums.length <= 3 * 10^4
  • 1 <= nums[i] <= 1000
  • 0 <= k <= 10^6

题目思考

  1. 如何尽可能优化时间复杂度?

解决方案

思路

  • 分析题目, 最容易想到的做法就是暴力两重循环: 遍历每个下标起点, 累乘当前的数字, 当前乘积小于 k 时计入最终结果
  • 但这种做法时间效率太低 (O(N^2)), 如何优化呢?
  • 注意到题目提到输入是正整数数组, 我们可以针对这一点对暴力法进行优化
  • 假设外层遍历到 i 作为起点, 内层遍历到下标 j 时子数组乘积大于等于了 k
  • 此时我们可以直接跳出内层循环 (因为数组元素全是正整数, 后面的子数组乘积只会更大), 无需继续遍历后面的数字, 并以 i+1 作为起点重新开始遍历
  • 但就算有了上述优化, 对于所有子数组乘积都小于 k 的情况, 时间复杂度仍是O(N^2)
  • 回过头再看暴力法, 每次子数组不满足要求时, 都需要从上个起点加 1 处重新开始内层遍历, 这样其实是没必要的
  • 因为[i+1,j]的子数组乘积可以直接根据[i,j]的子数组乘积计算得到, 即除以nums[i], 完全可以用常数时间判断子数组[i+1,j]是否满足要求
  • 所以更优化的做法是固定当前的终点 j, 将起点 i 继续向右移动, 并更新子数组乘积, 直到子数组乘积小于 k, 此时[i,j]窗口内的以 j 为终点的子数组都满足条件, 将其个数计入最终结果, 并继续遍历下一个终点 j 即可
  • 这样起点和终点都只需要遍历一遍, 时间复杂度降到了 O(N)
  • 以上就是典型的滑动窗口的思想, 通常做法就是维护双指针代表窗口起点和终点, 然后根据当前窗口是否满足要求来进行不同的处理
  • 下面代码中对上述每个步骤都有详细注释, 方便大家理解

复杂度

  • 时间复杂度 O(N): 最多遍历数组每个元素两遍
  • 空间复杂度 O(1): 只使用了几个常数空间的变量

代码

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        # 滑动窗口+前缀乘积
        res = 0
        cur = 1
        i = 0
        for j, num in enumerate(nums):
            # 累乘当前数字
            cur *= num
            while i <= j and cur >= k:
                # 注意窗口长度不能小于0, 所以需要额外限制条件i<=j
                cur //= nums[i]
                i += 1
            # [i,j]窗口内以j为终点的子数组的乘积都小于k, 可以计入最终结果
            # 注意i可能是j+1, 此时窗口长度为0, 表示不存在以j为终点的乘积小于k的子数组
            res += j - i + 1
        return res

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

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

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

相关文章

处方眼镜镜片在线定制类跨境电商独立站怎么做?

对于处方眼镜镜片&#xff0c;有很多的参数&#xff0c;对于在线类跨境电商商城&#xff0c;需要用户一步一步的提交很多的眼镜参数&#xff0c;下面是fecify眼镜镜片参数的定制过程, fecify的眼镜定制插件提供强有力的支持&#xff0c;下面是处方眼镜镜片在线定制类跨境电商独…

为什么Windows错误报告叫作Dr. Watson?

应该有一部分人可能会知道&#xff0c;Windows 错误报告有一个昵称&#xff0c;叫做”Dr. Watson”(华生医生)&#xff0c;没事&#xff0c;你不知道&#xff0c;也没关系。 今天的文章主要是讲讲&#xff0c;这个”Dr. Watson”名称的来历。 和你所猜想的一样&#xff0c;Dr.…

Java高手速成 | Java集合类泛类型

Java高手是这样炼成的。 01、Java集合类包括哪些&#xff1f; 作为学习集合类泛类型的预备知识&#xff0c;图1列出了Java集合类继承图。要学会集合类泛类型&#xff0c;除了懂得集合类外&#xff0c;大家也需 要了解继承的工作原理。图中虚线表示Collection是一个接口。 02…

Java-性能分析监控工具

Java监控和管理 Java监控和管理API Java Standard Edition&#xff08;Java SE&#xff09;平台提供的监控和管理技术 - JMX&#xff08;Java Management Extensions&#xff09; 技术。 Java SE 中包含了用于监控和管理的&#xff08;java.lang.management&#xff09;API&…

RabbitMQ 总结一(简介、安装、Demo)

目录 什么是MQ RabbitMQ和netty是什么关系 作用 流量削峰 应用解耦 异步处理 MQ的构成 生产者 交换机 队列 消费者 下载安装 案例Demo producer 第一步&#xff0c; 定义好连接的信息并且拿到连接&#xff0c;一般一个consumer/ producer 和broker只会建立一条连…

mysql之日志

前言 一条数据在更新过程当中&#xff0c;如果中途 mysql crash 了&#xff0c;mysql 是如何保证数据的一致性和持久性的&#xff1f;在这个过程中 mysql 的日志系统起到了至关重要的作用。本文将会介绍 mysql 中的 undo log、redo log 和 bin log 在这其中的作用。 buffer p…

230109-MacOS解决brew安装慢的问题

MacOS解决brew安装慢的问题 原文请移步参考&#xff1a; https://www.zhihu.com/question/46963138 cd "$(brew --repo)" git remote set-url origin https://mirrors.ustc.edu.cn/brew.gitecho export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.ustc.edu.cn/homebrew…

2022年度大赏 | UWA问答精选

UWA每周推送的知识型栏目《厚积薄发 | 技术分享》已经伴随大家走过了304个工作周。精选了2022年十大精彩问答分享给大家&#xff0c;期待2022年UWA问答继续有您的陪伴。 Q1&#xff1a;动态获取URP设置里自定义的RenderFeatures 我们在URP项目中自定义了多个RenderFeatures去实…

2022年度总结,以及2023的全新展望

时光总是在你的不经意间流逝&#xff0c;无法挽留&#xff1b;留得住的是你过去的努力和回忆&#xff0c;它也许充斥着快乐、忧伤、病痛等等。俗话说得好“笑一笑十年少”&#xff0c;那么我希望与快乐随行&#xff0c;让痛苦尘封记忆。让我们总结过去&#xff0c;展望未来&…

Python tkinter -- 第18章 画布控件之矩形

18.2.20 create_rectangle(bbox, **options) 根据限定矩形 bbox&#xff0c;在画布上创建一个矩形。新创建的对象位于显示的最前端。 &#xff08;1&#xff09;bbox&#xff1a;定义要创建对象的边界(x1, y1, x2, y2) &#xff08;2&#xff09;options&#xff1a; 选项的具体…

ICESat数据下载

ICESat数据下载1. ICESat简介2. ICESat数据产品2.1 GLA01数据2.2 GLA14数据3. 数据下载4. 总结1. ICESat简介 2003年美国国家航空航天局NASA ( National Aeronautics and SpaceAdministration)发射冰、云和陆地高程卫星ICESat&#xff0c;其上搭载的地球科学激光测高系统GLAS是…

基于YOLOv5的智能人脸数据标注工具源码,实现人脸数据标注自动化,可导出PASCAL VOC XML、MS COCO JSON

基于YOLOv5的智能人脸数据标注工具&#xff0c;实现人脸数据标注自动化 可自定义人脸检测模型、可导出多种格式标签&#xff0c;包括PASCAL VOC XML、MS COCO JSON、YOLO TXT 下载地址&#xff1a;基于YOLOv5的智能人脸数据标注工具源码&#xff0c;实现人脸数据标注自动化 …

智能黑白图像自动上色——C++实现

前言 《Colorful Image Colorization》是加里福利亚大学Richard Zhang发表在ECCV 2016上的文章&#xff0c;论文主要解决的问题是给灰度图的自动着色&#xff0c;算法并不是为恢复灰度图的真实颜色&#xff0c;而是用灰度图中物体的纹理、语义等信息作为线索&#xff0c;来预测…

Gradle学习笔记01

一、Gradle视频介绍新一代构建工具Gradle&#xff0c;提到项目自动化构建工具&#xff0c;首先提到的是Maven。现在谈谈Gradle与Maven之间的差异&#xff1a;同样作为项目自动化构建工具&#xff0c;Maven更侧重于项目jar包的管理&#xff0c;而Gradle侧重于项目的构建&#xf…

卷积层、卷积层里的填充和步幅

多层感知机正式总结卷积层之前&#xff0c;先把上次多层感知机落下的一点内容补一补。几个概念&#xff1a;训练数据集&#xff1a;训练模型参数。验证数据集&#xff1a;选择模型超参数。训练误差&#xff1a;模型在训练数据上的误差。泛化误差&#xff1a;模型在新数据上的误…

Linux常用命令——lftp命令

在线Linux命令查询工具 lftp 优秀的文件客户端程序 补充说明 lftp命令是一款优秀的文件客户端程序&#xff0c;它支持ftp、SETP、HTTP和FTPs等多种文件传输协议。lftp支持tab自动补全&#xff0c;记不得命令双击tab键&#xff0c;就可以看到可能的选项了。 语法 lftp(选项…

基于PCAP搭建软HUB实现物联网在线调试

完整工程可从以下地址签出&#xff1a; https://gitcode.net/coloreaglestdio/pcaphub.git 1.需求场景 在调试嵌入式物联设备时&#xff0c;尤其是在多个以太网物联设备交错通信的情况下&#xff0c;很难通过在捉襟见肘的嵌入式系统上进行数据记录与调试。如果设备连接的是一…

基于Kintex-7 FPGA的核心板电路设计

1. 引言Field Programmable GateArray&#xff08;简称&#xff0c;FPGA&#xff09;于1985年由XILINX创始人之一Ross Freeman发明&#xff0c;第一颗FPGA芯片XC2064为XILINX所发明&#xff0c;FPGA一经发明&#xff0c;后续的发展速度之快&#xff0c;超出大多数人的想象&…

系分 - 案例分析 - 需求获取

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 需求获取需求获取方法典型例题题目描述参考答案系分 - 案例分析 - 需求获取 需求获取方法 用户访谈 工作内容要点准备访谈步骤&#xff1a;1 确定访谈目的。2 确定访谈哪些用户。3 准…

PHP 文件上传

通过 PHP&#xff0c;可以把文件上传到服务器。 本章节实例在 test 项目下完成&#xff0c;目录结构为&#xff1a; test |-----upload # 文件上传的目录 |-----form.html # 表单文件 |-----upload_file.php # php 上传代码 源码下载 创建一个文件上…