题目描述
给你一个下标从
0
0
0开始的二维整数数组
t
r
a
n
s
a
c
t
i
o
n
s
transactions
transactions,其中
t
r
a
n
s
a
c
t
i
o
n
s
[
i
]
=
[
c
o
s
t
i
,
c
a
s
h
b
a
c
k
i
]
transactions[i]=[cost_i, cashback_i]
transactions[i]=[costi,cashbacki] 。
数组描述了若干笔交易。其中每笔交易必须以某种顺序恰好完成一次。在任意一个时刻,你有一定数目的钱
m
o
n
e
y
money
money,为了完成交易
i
i
i,
m
o
n
e
y
>
=
c
o
s
t
i
money>=cost_i
money>=costi这个条件必须为真。执行交易后,你的钱数
m
o
n
e
y
money
money变成
m
o
n
e
y
−
c
o
s
t
i
+
c
a
s
h
b
a
c
k
i
money-cost_i+cashback_i
money−costi+cashbacki。请你返回任意一种交易顺序下,你都能完成所有交易的最少钱数
m
o
n
e
y
money
money是多少。
示例1
输入: t r a n s a c t i o n s transactions transactions = [ [ 2 , 1 ] , [ 5 , 0 ] , [ 4 , 2 ] ] [ [2,1], [5,0], [4,2] ] [[2,1],[5,0],[4,2]]
输出: 10 10 10
解释:
刚开始 m o n e y = 10 money = 10 money=10,交易可以以任意顺序进行。
可以证明如果 m o n e y < 10 money < 10 money<10,那么某些交易无法进行。
示例2
输入: t r a n s a c t i o n s = [ [ 3 , 0 ] , [ 0 , 3 ] ] transactions = [ [3,0],[0,3] ] transactions=[[3,0],[0,3]]
输出: 3 3 3
解释:
1.如果交易执行的顺序是 [ [ 3 , 0 ] , [ 0 , 3 ] ] [[3,0],[0,3]] [[3,0],[0,3]],完成所有交易需要的最少钱数是 3 3 3。
2.如果交易执行的顺序是 [ [ 0 , 3 ] , [ 3 , 0 ] ] [[0,3],[3,0]] [[0,3],[3,0]],完成所有交易需要的最少钱数是 0 0 0。
所以,刚开始钱数为 3 3 3,任意顺序下交易都可以全部完成。
提示
- 1 < = t r a n s a c t i o n s . l e n g t h < = 1 0 5 1 <= transactions.length <= 10^5 1<=transactions.length<=105
- t r a n s a c t i o n s [ i ] . l e n g t h = = 2 transactions[i].length == 2 transactions[i].length==2
- 0 < = c o s t i , c a s h b a c k i < = 1 0 9 0 <= cost_i, cashback_i <= 10^9 0<=costi,cashbacki<=109
题解&碎碎念
题目倒是很简单,很容易能看懂,在 l e e t c o d e leetcode leetcode里是困难题,一开始以为是 D P DP DP,看了题解才发现是贪心(啊啊啊啊啊
- 题目要算的是任意情况下的最初 m o n e y money money,也就是要算在最差的情况下的 m o n e y money money
- 最差的情况,即先亏损后盈利(也是就是先算 c o s t − c a s h b a c k > 0 cost-cashback>0 cost−cashback>0的情况,先不断地亏钱亏钱亏钱)
- 在先亏损后盈利的情况下,有两个特殊的地方,即最后一次亏损和第一次盈利
- 先说第一次盈利,如果能盈利的交易是五个,且它的 c o s t cost cost是 3 3 3、 8 8 8、 1 1 1、 5 5 5、 6 6 6,那么我们希望在最后一次亏损时剩下的钱应该大于等于 8 8 8,才够后续的交易
- 再说最后一次亏损,此时的 c a s h b a c k cashback cashback一定是最大的,因为在亏损时,我们一定希望前期亏损越大越好,前期亏损越大,那么留在手里的 m o n e y money money就越少,情况也就越差
- 此时就可知,当整体交易有盈利交易时, m o n e y = money= money=全部亏损的金额 + + +盈利时最大的 c o s t cost cost
- 当整体交易都是亏损交易时,由于我们计划一次性计算所有亏损的金额,需要再重新计算最后一次交易时的金额,即全部亏损的金额 − ( c o s t + c a s h b a c k ) + c o s t -(cost+cashback)+cost −(cost+cashback)+cost,即 m o n e y = money= money=全部亏损的金额 + + +亏损时最大的 c a s h b a c k cashback cashback
- l e e t c o d e leetcode leetcode的官方题解说的是,如果当前交易是盈利交易或是亏损交易时,则xxxxx,但是我发现如果只说当前,对照着代码有点理解不上去,因此我就改为整体交易是盈利交易或是亏损交易时,此时除了计算全部亏损的金额,还要在每一次遍历时计算最大的 c o s t cost cost和 c a s h b a c k cashback cashback,这里不判断到底是盈利还是亏损,通过 m i n ( c o s t , c a s h b a c k ) min(cost, cashback) min(cost,cashback)的方式获取即可
class Solution {
public:
long long minimumMoney(vector<vector<int>>& transactions) {
long long sum_lost=0;
int c=0;
for (auto t: transactions) {
int cost=t[0], cash=t[1];
if (cost>cash) {
sum_lost+=cost-cash;
}
c=max(c, min(cost, cash));
}
return c+sum_lost;
}
};