Leetcode 春季赛:最小化舍入误差以满足目标(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/89301678

给定一系列价格 [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. 1 <= prices.length <= 500
  2. 表示价格的每个字符串 prices[i] 都代表一个介于 0 和 1000 之间的实数,并且正好有 3 个小数位。
  3. target 介于 0 和 1000000 之间。

解题思路

我们首先通过向上取整函数ceil和向下取整函数floor获取对应数组值。我们计算floor数组的和为res1ceil数组的和为res2,如果res1 > target or target > res2,那么返回"-1"

接着我们计算原先数组prices变成floor后每个数的变化,记录在数组dif中。接着对dif排序,因为我们希望最后的结果需要误差最小。那么我们需要多少个数向下取整呢?我们知道res1变成target需要target-res11,那么也就是说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

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/89301678