当前位置: 首页 > news >正文

2760. 最长奇偶子数组 : 抽丝剥茧,图解双指针做法正确性

题目描述

这是 LeetCode 上的 「2698. 求一个整数的惩罚数」 ,难度为 「简单」

Tag : 「双指针」、「滑动窗口」

给你一个下标从 开始的整数数组 nums 和一个整数 threshold

请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 ( ) 且满足以下条件的 最长子数组 :

  • nums[l] % 2 == 0
  • 对于范围 内的所有下标 inums[i] % 2 != nums[i + 1] % 2
  • 对于范围 内的所有下标 inums[i] <= threshold

以整数形式返回满足题目要求的最长子数组的长度。

注意:子数组 是数组中的一个连续非空元素序列。

示例 1:

输入:nums = [3,2,5,4], threshold = 5

输出:3

解释:在这个示例中,我们选择从 l = 1 开始、到 r = 3 结束的子数组 => [2,5,4] ,满足上述条件。
因此,答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。

示例 2:

输入:nums = [1,2], threshold = 2

输出:1

解释:
在这个示例中,我们选择从 l = 1 开始、到 r = 1 结束的子数组 => [2] 。
该子数组满足上述全部条件。可以证明 1 是满足题目要求的最大长度。

示例 3:

输入:nums = [2,3,4,5], threshold = 4

输出:3

解释:
在这个示例中,我们选择从 l = 0 开始、到 r = 2 结束的子数组 => [2,3,4] 。 
该子数组满足上述全部条件。
因此,答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。

提示:

双指针

整体题意:找 nums 中的最长的子数组 ,对于任意 不超过 threshold,且从 开始按照「先偶后奇」顺序交替。

假设子数组的左端点为 i,且“最远的”合法右端点为 j,那么在 之间的任意右端点 k,即使能够使得 合法,对统计答案而言,也是没有意义的,因为我们求的是最长。

基于此,我们容易想到:「找到所有的合法左端点 i,并统计该合法左端点的最远右端点 j。跳过 之间的点作为左端点的情况,直接从结束位置 j 开始找下一个合法左端点。」

该做法可将朴素的 做法优化至

但,这做法为什么是正确的?

我们只考虑了 中间点作为右端点的情况,那作为左端点呢?为什么跳过 之间的 作为左端点,正确性也不受影响?我们不是漏到了某些方案吗?

答案:「是漏掉了,但也只是漏掉了那些必不可能是最长子数组的方案」

alt

具体的,我们重新整理上述的「双指针」做法:

  • 从前往后扫描 nums,变量 i 作为当前子数组左端点,首先确保 i 的合法性(跳过不满足 nums[i] % 2 = 0nums[i] <= threshold 的位置)
  • 随后在固定左端点 i 前提下,找最远的(第一个不满足要求的)右端点 j(值不超过 threshold,且奇偶性与前值交替)
  • 得到当前连续段长度 ,更新 ans,从当前结束位置 j 开始,重复上述过程,直到处理完 nums

Java 代码

class Solution {
    public int longestAlternatingSubarray(int[] nums, int threshold) {
        int n = nums.length, ans = 0, i = 0;
        while (i < n) {
            if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0continue;
            int j = i + 1, cur = nums[i] % 2;
            while (j < n) {
                if (nums[j] > threshold || nums[j] % 2 == cur) break;
                cur = nums[j++] % 2;
            }
            ans = Math.max(ans, j - i);
            i = j;
        }
        return ans;
    }
}

C++ 代码:

class Solution {
public:
    int longestAlternatingSubarray(vector<int>& nums, int threshold) {
        int n = nums.size(), ans = 0, i = 0;
        while (i < n) {
            if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0continue;
            int j = i + 1, cur = nums[i] % 2;
            while (j < n) {
                if (nums[j] > threshold || nums[j] % 2 == cur) break;
                cur = nums[j++] % 2;
            }
            ans = max(ans, j - i);
            i = j;
        }
        return ans;
    }
};

Python 代码:

class Solution:
    def longestAlternatingSubarray(self, nums: List[int], threshold: int) -> int:
        n, ans, i = len(nums), 00
        while i < n:
            if nums[i] % 2 != 0 or nums[i] > threshold:
                i += 1
                continue
            j, cur = i + 1, nums[i] % 2
            while j < n:
                if nums[j] > threshold or nums[j] % 2 == cur: break
                cur, j = nums[j] % 2, j + 1
            ans = max(ans, j - i)
            i = j
        return ans

TypeScript 代码:

function longestAlternatingSubarray(nums: number[], threshold: number): number {
    let n = nums.length, ans = 0, i = 0
    while (i < n) {
        if ((nums[i] % 2 != 0 || nums[i] > threshold) && ++i >= 0continue;
        let j = i + 1, cur = nums[i] % 2;
        while (j < n) {
            if (nums[j] > threshold || nums[j] % 2 == cur) break;
            cur = nums[j++] % 2;
        }
        ans = Math.max(ans, j - i);
        i = j;
    }
    return ans;
};
  • 时间复杂度:
  • 空间复杂度:

最后

这是我们「刷穿 LeetCode」系列文章的第 No.2760 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

相关文章:

2760. 最长奇偶子数组 : 抽丝剥茧,图解双指针做法正确性

题目描述 这是 LeetCode 上的 「2698. 求一个整数的惩罚数」 &#xff0c;难度为 「简单」。 Tag : 「双指针」、「滑动窗口」 给你一个下标从 开始的整数数组 nums 和一个整数 threshold。 请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 ( ) 且满足以下条件的 最长子…...

在Linux系统中创建虚拟串口

在Linux系统中创建虚拟串口 文章目录 在Linux系统中创建虚拟串口1、虚拟串口介绍2、使用 socat创建虚拟串行端口2.1 安装socat2.2 创建简单的虚拟串口2.3 创建指定波特率的串行端口 有多种方法可以在 Linux 中创建虚拟串口来测试和调试串行通信协议。 在本文中&#xff0c;我们…...

无线WiFi安全渗透与攻防(五) Kali使用mdk3攻击wifi(详细教程)以及相关周边知识

Kali使用mdk3攻击wifi(详细教程) 一. 网络安全--Kali使用mdk3攻击wifi(详细教程)一.前言二.准备1.网卡2.虚拟机3.系统三.原理1.原理2.步骤四.实战1.网卡设置1.1查看网卡1.2.切换网卡模式1.3再次查看网卡2.AP扫描3.mdk3创建虚拟wifi1.创建一个虚拟wifi2.创建大量wifi4.扫描…...

Mac电脑好用的窗口管理软件 Magnet 中文for mac

Magnet是一款用于Mac操作系统的窗口管理工具&#xff0c;它可以帮助您快速和方便地组织和管理应用程序窗口&#xff0c;以提高您的工作效率和多任务处理能力。 以下是Magnet的一些主要功能和特点&#xff1a; 窗口自动调整&#xff1a;Magnet允许您通过简单的拖放操作或使用快…...

除了Excel中可以添加公式之外,在Word中也可以添加公式,不过都是基于表格

公式是必不可少的,因为它们有助于简化任何数学任务。微软的应用程序中有许多数学公式。微软应用程序之一的Word配备了一个公式功能,可以执行各种操作。本文将讨论如何在Word中使用和添加公式。 在Word中,公式主要用于表格。因此,你需要有一个表格才能在Word中使用公式。 …...

【华为OD题库-017】矩阵稀疏扫描-Java

题目 如果矩阵中的许多系数都为零&#xff0c;那么该矩阵就是稀疏的。对稀疏现象有兴趣是因为它的开发可以带来巨大的计算节省&#xff0c;并且在许多大的实践中都会出现矩阵稀疏的问题。给定一个矩阵&#xff0c; 现在需要逐行和逐列地扫描矩阵&#xff0c;如果某一行或者某一…...

相机通用类之LMI激光三角相机(3D),软触发硬触发(飞拍),并输出halcon格式对象

//在此之前可以先浏览我编写的通用上位机类&#xff0c;更方便理解 https://blog.csdn.net/m0_51559565/article/details/134403745最近完成一个关于LMI激光三角&#xff08;3D相机&#xff09;采图的demo&#xff0c;记录并说明用法。 先上代码。 using Lmi3d.GoSdk; using L…...

android studio基本使用

as如果一直index&#xff0c;就把缓存目录全部删除 记录下as日常使用。 调试工具 c动态库调试 ndk会带一些调试工具&#xff0c;例如 C:\Users\luopu\AppData\Local\Android\Sdk\ndk\20.0.5594570\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch…...

安装包管理工具-Yarn

一、介绍与安装 1.1 介绍 Yarn是一款功能包管理工具&#xff0c;与npm(npm:Node.js 的包管理器 npm,是目前最流行的Node.js 的包管理器。)类似。有着FAST(快速的), RELIABLE( RELIABLE 可信赖的), AND SECURE DEPENDENCY MANAGEMENT(安全依赖关系管理)的特点。 Yarn官网 1.2…...

SOLIDWORKS功能布局实用技巧之保存实体技术

在SOLIDWORKS软件中&#xff0c;有一些命令可以将一个或多个实体保存为独立的零件文件。然而&#xff0c;每个命令都具有不同的特性&#xff0c;有些命令的选项可以让您在保存多个零件时直接生成装配体文件。让我们来深入了解这些功能布局技巧&#xff0c;特别是实体保存技术。…...

Android11 将logcat日志定位到uart串口输出

软件平台&#xff1a;Android11 硬件平台&#xff1a;QCS6125 需求&#xff1a;如题&#xff0c;串口需要输出logcat的系统全量日志&#xff0c;我这里边是把logcat日志定向到了/dev/kmsg从而使logcat跟kmsg一样通过串口输出。 改动如下&#xff1a; diff --git a/rootdir/…...

SpringSecurity6从入门到上天系列第六篇:解决这个问题为什么在引入SpringSecurity之后所有的请求都需要先做登录认证才可以进行访问呢

文章目录 问题引入 1&#xff1a;问题阐述 2&#xff1a;问题分析 一&#xff1a;从SpringBoot的自动装配 1&#xff1a;SpringBootApplication介绍 2&#xff1a;自动装配的核心方法 3&#xff1a;核心方法的调用路径 4&#xff1a;SpringSecurity核心配置 5&#xf…...

Mac M3 芯片安装 Nginx

Mac M3 芯片安装 Nginx 一、使用 brew 安装 未安装 brew 的可以参考 【Mac 安装 Homebrew】 或者 【Mac M2/M3 芯片环境配置以及常用软件安装-前端】 二、查看 nginx 信息 通过命令行查看 brew info nginx可以看到 nginx 还未在本地安装&#xff0c;显示 Not installed …...

浏览器怎么更新?4个高效设置方法!

“我在使用浏览器时&#xff0c;有时候会提示说浏览器版本太低&#xff0c;需要更新后才能使用。有什么方法可以更新浏览器呢&#xff1f;快给我支支招吧&#xff01;” 在快速发展的科技时代&#xff0c;浏览器更新是确保网络安全和性能优化的关键步骤。如果浏览器的版本太低&…...

settings.json配置

settings.json配置 {"editor.tabSize": 2,"git.ignoreWindowsGit27Warning": true,"workbench.editor.untitled.hint": "hidden","security.workspace.trust.untrustedFiles": "open","[vue]": {"…...

Mysql中的JDBC编程

JDBC编程 1.JDBC的数据库编程2.JDBC工作原理3.JDBC使用3.1JDBC开发案例3.2JDBC使用步骤总结 4.JDBC API4.1数据库连接Connection4.2 Statement对象4.3 ResultSet对象4.4 释放 5.Java代码操作数据库 1.JDBC的数据库编程 JDBC&#xff0c;即Java Database Connectivity&#xff0…...

媒体行业的3D建模:在影视中创造特效纹理

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 在本文中&#xff0c;我们将探讨 3D 建模在媒体行业中的作用&#xff0c;特别是它在影视特效创作…...

Kafka从安装使用到集成Springboot详细教程

“不积跬步&#xff0c;无以至千里。” 1. 引言 在当今高度互联的技术领域&#xff0c;消息队列成为分布式系统中不可或缺的一部分。Apache Kafka作为一个高性能、持久化、分布式的消息队列系统&#xff0c;备受开发者推崇。这篇文章将从安装到集成Spring的全方位介绍Kafka的使…...

【giszz笔记】产品设计标准流程【4】

&#xff08;续上回&#xff09; 我们继续把扩展考虑UX环节的产品打造标准流程&#xff0c;来进行梳理。 一千个人心中有一千个哈姆雷特&#xff0c;本文将日常大家耳熟能详&#xff0c;但是又未必人人心中成体系的产品打造标准流程&#xff0c;进行总结。 考虑了两种项目&a…...

图论16-拓扑排序

文章目录 1 拓扑排序2 拓扑排序的普通实现2.1 算法实现 - 度数为0入队列2.2 拓扑排序中的环检测 3 深度优先遍历的后续遍历3.1 使用环检测类先判断是否有环3.2 调用无向图的深度优先后续遍历方法&#xff0c;进行DFS 1 拓扑排序 对一个有向无环图G进行拓扑排序&#xff0c;是将…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...

NineData数据库DevOps功能全面支持百度智能云向量数据库 VectorDB,助力企业 AI 应用高效落地

NineData 的数据库 DevOps 解决方案已完成对百度智能云向量数据库 VectorDB 的全链路适配&#xff0c;成为国内首批提供 VectorDB 原生操作能力的服务商。此次合作聚焦 AI 开发核心场景&#xff0c;通过标准化 SQL 工作台与细粒度权限管控两大能力&#xff0c;助力企业安全高效…...