zoukankan      html  css  js  c++  java
  • 算法与数据结构-最小化舍入误差以满足目标

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

    题目

    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();
        }
    }
    
  • 相关阅读:
    document.getElementById IE bug
    Add Event
    start silverlight
    【转】MSDN magzine JavaScript使用面向对象的技术创建高级 Web 应用程序
    文本编辑工具Vim
    《JavaScript DOM编程艺术》附录(dom方法和属性)
    js variable undefined
    good tools 调试好帮手
    my pretty code
    万级访问网站前期的技术准备(下)
  • 原文地址:https://www.cnblogs.com/ging/p/14252388.html
Copyright © 2011-2022 走看看