【Leetcode】2106. 摘水果

文章目录

  • 题目
  • 思路
  • 代码
    • C++
    • Java
    • Python
  • 复杂度分析
    • 时间复杂度
    • 空间复杂度
  • 结果
  • 总结

题目

题目链接🔗

在一个无限的 x 坐标轴上,有许多水果分布在其中某些位置。给你一个二维整数数组 fruits ,其中 fruits[i] = [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上。fruits 已经按 positioni 升序排列 ,每个 positioni 互不相同 。

另给你两个整数 startPos 和 k 。最初,你位于 startPos 。从任何位置,你可以选择 向左或者向右 走。在 x 轴上每移动 一个单位 ,就记作 一步 。你总共可以走 最多 k 步。你每达到一个位置,都会摘掉全部的水果,水果也将从该位置消失(不会再生)。

返回你可以摘到水果的 最大总数 。

示例 1:
在这里插入图片描述

输入:fruits = [[2,8],[6,3],[8,6]], startPos = 5, k = 4
输出:9
解释:
最佳路线为:

  • 向右移动到位置 6 ,摘到 3 个水果
  • 向右移动到位置 8 ,摘到 6 个水果
    移动 3 步,共摘到 3 + 6 = 9 个水果

示例 2:
在这里插入图片描述

输入:fruits = [[0,9],[4,1],[5,7],[6,2],[7,4],[10,9]], startPos = 5, k = 4
输出:14
解释:
可以移动最多 k = 4 步,所以无法到达位置 0 和位置 10 。
最佳路线为:

  • 在初始位置 5 ,摘到 7 个水果
  • 向左移动到位置 4 ,摘到 1 个水果
  • 向右移动到位置 6 ,摘到 2 个水果
  • 向右移动到位置 7 ,摘到 4 个水果
    移动 1 + 3 = 4 步,共摘到 7 + 1 + 2 + 4 = 14 个水果

示例 3:
在这里插入图片描述

输入:fruits = [[0,3],[6,4],[8,5]], startPos = 3, k = 2
输出:0
解释:
最多可以移动 k = 2 步,无法到达任一有水果的地方

提示:

1 <= fruits.length <= 105
fruits[i].length == 2
0 <= startPos, positioni <= 2 * 105
对于任意 i > 0 ,positioni-1 < positioni 均成立(下标从 0 开始计数)
1 <= amounti <= 104
0 <= k <= 2 * 105

思路

本题的核心是求解从起始位置startPos出发,最多走k步所能摘到的最大水果数量。考虑到路径可能涉及向左或向右先走然后折返,我们可以枚举可能的右侧最远位置R(从startPos到startPos + k的范围),计算对应步数sr = R - startPos,然后计算在剩余步数下能到达的最左侧距离dd。dd通过两种策略计算:先向左走然后向右到R(dd <= (k - sr)/2),或先向右到R然后向左(dd <= k - 2*sr),取两种策略的最大dd,并clamp到[0, startPos]。使用数组arr存储每个位置的水果数量,left数组预计算从startPos向左的累加和。最后,对于每个R,计算从startPos - dd到R的水果总量,取最大值。这种方法高效地覆盖了所有可能路径,并确保在O(N)时间内求解,其中N = max(startPos, 最大位置) <= 4e5。

代码

C++

class Solution {
public:int maxTotalFruits(vector<vector<int>>& fruits, int startPos, int k) {int n = max(startPos, fruits.back()[0]);vector<int> arr(n + 1, 0);for(auto& x : fruits) arr[x[0]] += x[1];vector<int> left(n + 1, 0);// 向左走 startPos - i 步int last = 0;for(int i = startPos; i >= 0; i --) {left[startPos - i] = last + arr[i];last = left[startPos - i];}int x = 0, res = 0;for(int i = startPos; i <= min(startPos + k, n); i ++) {if(i != startPos) x += arr[i];int sr = i - startPos; // 向右走了 sr 步// 最多向左走了几步// l -> r// (k-sr)/2// r -> l// k - 2 * srres = max(res, x + left[min(startPos, max((k-sr)/2, k-2*sr))]);}return res;}
};

Java

class Solution {public int maxTotalFruits(int[][] fruits, int startPos, int k) {int n = Math.max(startPos, fruits[fruits.length - 1][0]);int[] arr = new int[n + 1];for (int[] x : fruits) {arr[x[0]] += x[1];}int[] left = new int[n + 1];int last = 0;for (int i = startPos; i >= 0; i--) {left[startPos - i] = last + arr[i];last = left[startPos - i];}int x = 0;int res = 0;int maxI = Math.min(startPos + k, n);for (int i = startPos; i <= maxI; i++) {if (i != startPos) {x += arr[i];}int sr = i - startPos;int cand1 = (k - sr) / 2;int cand2 = k - 2 * sr;int dd = Math.max(cand1, cand2);dd = Math.min(startPos, Math.max(0, dd));res = Math.max(res, x + left[dd]);}return res;}
}

Python

class Solution:def maxTotalFruits(self, fruits: List[List[int]], startPos: int, k: int) -> int:n = max(startPos, fruits[-1][0])arr = [0] * (n + 1)for p, a in fruits:arr[p] += aleft = [0] * (n + 1)last = 0for i in range(startPos, -1, -1):left[startPos - i] = last + arr[i]last = left[startPos - i]x = 0res = 0max_i = min(startPos + k, n)for i in range(startPos, max_i + 1):if i != startPos:x += arr[i]sr = i - startPoscand1 = (k - sr) // 2cand2 = k - 2 * srdd = max(cand1, cand2)dd = min(startPos, max(0, dd))res = max(res, x + left[dd])return res

复杂度分析

时间复杂度

O(N),其中N = max(startPos, 最大位置) <= 4 \times 10^5,预计算left数组和循环枚举右侧位置均为O(N)。

空间复杂度

O(N),用于存储arr和left数组。

结果

该解法通过了LeetCode的所有测试用例,运行时间和内存消耗均在可接受范围内。

总结

通过枚举右侧最远位置并计算最大左侧延伸距离,该方法巧妙地处理了路径折返的两种策略,确保了正确性和高效性。如果位置范围较大,可考虑使用前缀和优化进一步压缩空间,但当前实现已足够优秀。https://leetcode.cn/problems/maximum-fruits-harvested-after-at-most-k-steps/description/?envType=daily-question&envId=2025-08-03

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

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

相关文章

(CVPR 2024)SLAM卷不动了,机器人还有哪些方向能做?

关注gongzhonghao【CVPR顶会精选】众所周知&#xff0c;机器人因复杂环境适应性差、硬件部署成本高&#xff0c;对高效泛化一直需求迫切。再加上多传感器协同难题、真实场景数据获取不易&#xff0c;当下对迁移学习 机器人智能融合的研究也就更热烈了。不过显然&#xff0c;这…

Go语言 延 迟 语 句

延迟语句&#xff08;defer&#xff09;是Go 语言里一个非常有用的关键字&#xff0c;它能把资源的释放语句与申请语句放到距离相近的位置&#xff0c;从而减少了资源泄漏的情况发生。延迟语句是什么defer 是Go 语言提供的一种用于注册延迟调用的机制&#xff1a;让函数或语句可…

【go 】数组的多种初始化方式与操作

在 Go 语言中&#xff0c;数组是一种固定长度的数据结构&#xff0c;用于存储相同类型的元素。以下是 Go 中数组的多种初始化方式&#xff0c;结合搜索结果整理如下&#xff1a; &#xff08;一&#xff09;使用 var 关键字声明并初始化数组 使用 var 关键字声明数组时&#xf…

基于Java+MySQL 实现(Web)网上商城

悦桔拉拉商城1. 课设目的可以巩固自己之前所学的知识&#xff0c;以及学习更多的新知识。可以掌握业务流程&#xff0c;学习工作的流程。2. 开发环境硬件环境&#xff1a;Window11 电脑、Centos7.6 服务器软件环境&#xff1a;IntelliJ IDEA 2021.1.3 开发工具JDK 16 运行环境M…

高并发抢单系统核心实现详解:Redisson分布式锁实战

一、方法整体流程解析 #mermaid-svg-MROZ2xF7WaNPaztA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MROZ2xF7WaNPaztA .error-icon{fill:#552222;}#mermaid-svg-MROZ2xF7WaNPaztA .error-text{fill:#552222;strok…

Android12 User版本开启adb root, adb remount, su, 关闭selinux

开启adb root 直接看adb源码&#xff1a; __android_log_is_debuggable就是判断ro.debuggable属性值&#xff0c;感兴趣可以在 源码下grep下实现看看。auth_required :在adb源码下定义的全局变量&#xff0c;默认等于true,。看名字就是是否需要用户授权的flag, 这里不再继续跟…

金融专业高分简历撰写指南

一、金融求职简历原则&#xff1a;深度与亮点并存在金融行业求职时&#xff0c;一份出色的简历需突出经历深度与亮点。01 教育背景需如实填写毕业院校、专业、GPA及所学课程。金融行业不少公司对求职者学校和学历有严格标准&#xff0c;如“985”“211”院校或硕士以上学历等。…

专题:2025生命科学与生物制药全景报告:产业图谱、投资方向及策略洞察|附130+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43526 过去一年&#xff0c;全球生命科学VC融资回暖至1021.5亿美元&#xff0c;并购交易虽下滑23%却聚焦关键赛道&#xff0c;创新药管线中GLP-1受体激动剂以170亿美元市场规模领跑&#xff0c;AI技术将研发周期缩短60%……这些数据背…

Compose笔记(四十)--ClickableText

这一节主要了解一下Compose中的ClickableText&#xff0c;在Jetpack Compose中&#xff0c;ClickableText是用于创建可点击文本的组件&#xff0c;其核心功能是通过声明式语法将文本设置为交互式元素&#xff0c;用户点击时可触发特定操作。简单总结如下:API含义 text&#xff…

面试必刷的数组三连:原地删除与合并

坚持用 清晰易懂的图解 多语言代码&#xff0c;让每道题变得简单&#xff01; 呆头个人主页详情 呆头个人Gitee代码仓库 呆头详细专栏系列 座右铭&#xff1a; “不患无位&#xff0c;患所以立。” 面试必刷的数组三连&#xff1a;原地删除与合并前言目录1.移除元素2.删除有序…

力扣经典算法篇-41-旋转图像(辅助数组法,原地旋转法)

1、题干 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a;输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

译|用户增长策略如何使用因果机器学习的案例

来自上传文件中的文章《[Causal Machine Learning for Growth: Loyalty Programs, LTV, and What to Do When You Can’t Experiment | by Torty Sivill | Towards AI]》 本文探讨了当 A/B 测试不可行时&#xff0c;如何利用因果推断从历史数据中获取洞察。技术亮点在于通过构建…

java~final关键字

final关键字final基本介绍final的使用细节final基本介绍 final是最终的意思&#xff0c;可以修饰类&#xff0c;属性&#xff0c;方法&#xff0c;局部变量什么时候会要使用到final呢&#xff1f; 1.想要类不被继承时 2.不希望类的某个属性的值被改变时 3.不想父类的某个方法被…

Node.js(四)之数据库与身份认证

数据库与身份认证 目录 数据库与身份认证 十三、数据库的基本概念 13.1 什么是数据库 13.2 常见的数据库及分类 13.3 传统型数据库的数据组织结构 1. Excel 的数据组织结构 2. 传统型数据库的数据组织结构 3. 实际开发中库、表、行、字段的关系 十四、安装并配置MySQ…

SpringBoot+SpringMVC常用注解

文章目录发展历程项目创建项目结构入门案例配置文件的两种方式&#xff1a;只能使用一种创建项目二入门案例常用知识及注解Controller:类上面加&#xff0c;SpringMVC的注解GetMapping:方法上面加Spring框架的两项核心功能Component:组件。控制反转&#xff0c;加在业务类上面&…

标准GS相位恢复算法

标准GS相位恢复算法详解与MATLAB实现 Gerchberg-Saxton (GS) 算法是一种经典的相位恢复方法&#xff0c;广泛应用于光学成像、衍射成像和全息技术等领域。该算法通过迭代过程从未知相位的强度测量中恢复相位信息。 算法原理 GS算法的核心思想是利用傅里叶变换关系在空间域和频率…

【Linux网络编程基础--socket地址API】

一、主机字节序和网络字节序主机字节序&#xff08;Host Byte Order&#xff09;&#xff1a;你当前电脑的内存字节顺序&#xff08;比如 x86 是小端&#xff09;网络字节序&#xff08;Network Byte Order&#xff09;&#xff1a;统一规定为大端序&#xff08;高位字节在高位…

Linux路径MTU发现(Path MTU Discovery, PMTU)

Linux路径MTU发现&#xff08;Path MTU Discovery, PMTU&#xff09;机制是TCP/IP协议栈中确保数据包高效传输的核心技术。其核心目标是动态探测源主机到目的主机路径上的最小MTU&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;从而避免IP分片&#xff0c;提升…

【MySQL进阶】------MySQL程序

MySQL程序简介 MySQL安装完成通常会包含如下程序&#xff1a; Linux系统程序⼀般在 /usr/bin⽬录下&#xff0c;可以通过命令查看&#xff1a; windows系统⽬录&#xff1a;你的安装路径\MySQL Server 8.0\bin&#xff0c;可以通过命令查看&#xff1a; 每个 MySQL 程序都有许…

Linux大页内存导致服务内存不足

Linux大页内存导致服务内存不足的解决方法 大页内存&#xff08;Huge Pages&#xff09;是Linux内核提供的一种机制&#xff0c;用于减少TLB&#xff08;转换后备缓冲区&#xff09;的压力&#xff0c;提高内存访问性能。然而&#xff0c;如果配置不当&#xff0c;大页内存可能…