算法与数据结构-最小化舍入误差以满足目标

最小化舍入误差以满足目标

题目

leetcode原题:1058. 最小化舍入误差以满足目标

给定一系列价格 [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"
解释:
达到目标是不可能的。

解析

这道题的核心需要思考出:

  • 所有数据向上取整的整数和sumFloor-target的相差个数就是 结果中 ceil的个数

  • 所有数据向下取整的整数和sumCeil-target的相差个数就是 结果中 floor的个数

已知满足条件的解中的ceil和floor的个数,并且需要求最小误差和,那就分别正序排序floor和ceil的误差list

按照floor和ceil的个数相加得到总和即可!

代码

import java.math.BigDecimal;
class Solution {
    public String minimizeError(String[] prices, int target) {
       //生成相关待使用数据
       List<BigDecimal> floorList = new ArrayList<>(prices.length);
       List<BigDecimal> ceilList = new ArrayList<>(prices.length);
       int sumFloor = 0;
       int sumCeil = 0;
       

       for(String s:prices){
          String[] tmps = s.split("\.");
          int i = Integer.parseInt(tmps[0]);
          BigDecimal d = new BigDecimal("0."+ tmps[1]);
          sumFloor = sumFloor + i;
          if(!"000".equals(tmps[1])){
             sumCeil = sumCeil + i + 1;
          }else{
             sumCeil = sumCeil + i;
          }

          floorList.add(d);
          ceilList.add(new BigDecimal("1.000").subtract(d));
       }

       //判断target是否在sumFloor和sumCeil区间内
       if(target < sumFloor || target > sumCeil){
          return -1+"";
       }

       //确定floor和ceil的个数(直接用target-sumFloor计算得到)
       

       //排序舍入误差的两个数组,按照前一步计算得到的个数分别从小到大相加即可
       Collections.sort(floorList);
       Collections.sort(ceilList);
      
       BigDecimal finalResult = new BigDecimal("0.000");

       for(int i = 0;i < target-sumFloor;i++){
          finalResult = finalResult.add(ceilList.get(i));
       }

       
       for(int i=0;i<prices.length - (target-sumFloor);i++){
         finalResult = finalResult.add(floorList.get(i));
       }

       return finalResult.toString();
    }
}
原文地址:https://www.cnblogs.com/ging/p/14252388.html