给定一系列价格 [p1,p2...,pn]
和一个目标 target
,将每个价格 pi
舍入为 Roundi(pi)
以使得舍入数组 [Round1(p1),Round2(p2)...,Roundn(pn)]
之和达到给定的目标值 target
。每次舍入操作 Roundi(pi)
可以是向下舍 Floor(pi)
也可以是向上入 Ceil(pi)
。
如果舍入数组之和无论如何都无法达到目标值 target
,就返回 -1
。否则,以保留到小数点后三位的字符串格式返回最小的舍入误差,其定义为 Σ |Roundi(pi) - (pi)|( i 从 1 到 n )。
示例 1:
输入:prices = ["0.700","2.800","4.900"], target = 8
输出:"1.000"
解释:
使用 Floor,Ceil 和 Ceil 操作得到 (0.7 - 0) + (3 - 2.8) + (5 - 4.9) = 0.7 + 0.2 + 0.1 = 1.0 。
示例 2:
输入:prices = ["1.500","2.500","3.500"], target = 10
输出:"-1"
解释:
达到目标是不可能的。
提示:
1 <= prices.length <= 500
- 表示价格的每个字符串
prices[i]
都代表一个介于 0 和 1000 之间的实数,并且正好有 3 个小数位。 target
介于 0 和 1000000 之间。
解题思路
我们首先通过向上取整函数ceil
和向下取整函数floor
获取对应数组值。我们计算floor
数组的和为res1
,ceil
数组的和为res2
,如果res1 > target or target > res2
,那么返回"-1"
。
接着我们计算原先数组prices
变成floor
后每个数的变化,记录在数组dif
中。接着对dif
排序,因为我们希望最后的结果需要误差最小。那么我们需要多少个数向下取整呢?我们知道res1
变成target
需要target-res1
个1
,那么也就是说target-res1
个数需要向上取整,那么也就是会有n+res1-target
个数向下取整。
最后将所有误差加起来,然后输出即可。
import math
class Solution:
def minimizeError(self, prices: List[str], target: int) -> str:
n = len(prices)
prices = [float(i) for i in prices]
floor = [math.floor(i) for i in prices]
ceil = [math.ceil(i) for i in prices]
res1, res2 = sum(floor), sum(ceil)
if res1 > target or target > res2:
return "-1"
dif = [prices[i] - floor[i] for i in range(n)]
dif.sort()
res = 0
target = n + res1 - target
for i in range(target):
res += dif[i]
for i in range(target, n):
res += 1 - dif[i]
return "{:.3f}".format(res)
我发现了这个问题一个小bug
,如果不采用上面这种写法,而采用下面这种写法的话就无法通过
import math
class Solution:
def minimizeError(self, prices: List[str], target: int) -> str:
n = len(prices)
prices = [float(i) for i in prices]
floor = [math.floor(i) for i in prices]
ceil = [math.ceil(i) for i in prices]
res1, res2 = sum(floor), sum(ceil)
if res1 > target or target > res2:
return "-1"
dif1 = [ceil[i] - prices[i] for i in range(n)]
dif1.sort()
dif2 = [prices[i] - floor[i] for i in range(n)]
dif2.sort(reverse=True)
res = 0
target -= res1
for i in range(target):
res += dif1[i]
for i in range(target, n):
res += dif2[i]
return "{:.3f}".format(res)
我发现了这样做的误差来源1 - dif[i]
实际上会造成误差的累加。欢迎大家在评论去讨论!!O(∩_∩)O~
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!