LeetCode 5955. 摘水果

在一个无限的 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-fruits-harvested-after-at-most-k-steps
 

解法

前缀和+二分。周赛的时候脑子非常乱,本题的解题思路比较简单,但有许多关于下标的细节问题,最终在比赛结束后用自己凌乱的代码过了。去看完大佬的代码后,才知道可以写的这么简洁。随后自己编写了新的代码。

首先令x为先走一边的长度,那么另一边的长度为k-2*x.然后分为先走左还是先走右

class Solution {
public:
	int maxTotalFruits(vector<vector<int>>& fruits, int startPos, int k) {
		int n = fruits.size();
		vector<int> sum(n); //前缀和数组
		vector<int> pos(n); //位置信息
		

		for (int i = 0; i < n; ++i)
		{
			if (i==0)
				sum[0] = fruits[0][1];
			else 
				sum[i] = sum[i - 1] + fruits[i][1];
			pos[i] = fruits[i][0];
		}
		int ans = 0;
		for (int x = k; x >= 0; --x) //枚举先走一边的长度
		{
			int le =max(startPos - x, 0), r =max(startPos, startPos + (k - 2 * x));
			int l_id = lower_bound(pos.begin(), pos.end(), le) - pos.begin(), r_id = upper_bound(pos.begin(), pos.end(), r) - pos.begin();
			--r_id;                                     //如果将sum从下标1开始存储,--r_id和下面的if都不需要
			if (r_id >= 0 && l_id < n)
				ans = max(ans, sum[r_id] - sum[l_id] + fruits[l_id][1]);
			le =min(startPos, startPos-(k-2*x)), r = startPos+x;
			l_id = lower_bound(pos.begin(), pos.end(), le) - pos.begin(), r_id = upper_bound(pos.begin(), pos.end(), r) - pos.begin();
			--r_id;
			if (l_id < n&&r_id>0)
				ans = max(ans, sum[r_id] - sum[l_id] + fruits[l_id][1]);
		}
		return ans;
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值