算法 - 递归 数学分析 - 2335. 装满杯子需要的最短总时长 详细解析

embedded/2024/9/23 8:15:59/

2335. 装满杯子需要的最短总时长

文章目录

  • [2335. 装满杯子需要的最短总时长](https://leetcode.cn/problems/minimum-amount-of-time-to-fill-cups/description/)
    • 说明
    • 题解思路
      • 简单模拟 + 递归
      • 数学分析
    • Code
      • 简单模拟 + 递归
      • 数学分析

说明

现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。给你一个下标从 0 开始、长度为 3 的整数数组 amount ,其中 amount[0]、amount[1] 和 amount[2] 分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。示例 1:输入:amount = [1,4,2]
输出:4
解释:下面给出一种方案:
第 1 秒:装满一杯冷水和一杯温水。
第 2 秒:装满一杯温水和一杯热水。
第 3 秒:装满一杯温水和一杯热水。
第 4 秒:装满一杯温水。
可以证明最少需要 4 秒才能装满所有杯子。
示例 2:输入:amount = [5,4,4]
输出:7
解释:下面给出一种方案:
第 1 秒:装满一杯冷水和一杯热水。
第 2 秒:装满一杯冷水和一杯温水。
第 3 秒:装满一杯冷水和一杯温水。
第 4 秒:装满一杯温水和一杯热水。
第 5 秒:装满一杯冷水和一杯热水。
第 6 秒:装满一杯冷水和一杯温水。
第 7 秒:装满一杯热水。
示例 3:输入:amount = [5,0,0]
输出:5
解释:每秒装满一杯冷水。提示:amount.length == 3
0 <= amount[i] <= 100

题解思路

  • 按题意看,装满所有杯子需要的最少时间一定需要尽可能多的一次倒2杯水
  • 那么就可以转化为:尽量每次倒两种水,需要的时间

简单模拟 + 递归

  • 尽量每次倒两种水,需要的时间
  • 那么每次倒所需最多的次多的两种,最后如果有余那么加上这个时间
  • 按照题意模拟:
    • 每次先对数组进行排序
    • 如果仅有一种水的需求了,那么就返回这个需求的数量
    • 否则将最多的和次多的各减一
    • 操作数加一进行递归
  • 数组长度固定为 3 ,所以排序的时间复杂度为 O(1)
  • 最终时间复杂度仅取决于amount[n]的大小,为 O(n)
  • 空间复杂度为 O(1)

数学分析

  • 细看题目,实际上这个问题可以通过数学的方式来求解
  • 设定需求最多的水数量为 c , 次多的水数量为 b ,最少的水数量为 a
    • 如果 c >= a + b ,那么每次倒c水的时候,都能带走一杯 a 或者 b ,最终加上 c 的剩余即为最优的用时
      • 那就是每次都倒 c 的水,有 ab 的时候带上倒,没了就只倒 c ,最终的用时就是倒完 c 的时间
      • 最优的耗时就是 c的值
    • 如果 c < a + b
      • 这个情况的最优策略就取决于 a + bc 的差值 tt = a + b - c
        • 因为如果将在 t/2 的时间内,将 ab 合起来倒掉 t 杯水,那么问题就转化成了上面的c >= a + b,最优时间为 c
      • 现在就需要证明在 t/2 的时间内,能不能将 ab 合起来倒掉 t 杯水,这取决于 a 是否大于等于 t/2
      • 反证法:
        • 假设 a < t/2
        • => t < t/2 + b - c
        • => t/2 < b - c
        • 因为 b < c ,且t一定大于0,假设显然不成立
        • 那么就能证明 a 一定大于等于 t/2
      • 需要的时间就是先用 t/2 的时间将问题转化为 c >= a + b 的情况
      • 最终耗时:t/2 + c => (a + b - c)/2 + c
      • 实现需要考虑奇偶,所以为(a + b - c + 1)/2 + c
  • 时间复杂度为 O(1)
  • 空间复杂度为 O(1)

Code

简单模拟 + 递归

class Solution {public int fillCups(int[] amount) {Arrays.sort(amount);if(amount[1] == 0) return amount[2];amount[2]--;amount[1]--;return 1 + fillCups(amount);}
}

数学分析

class Solution {public int fillCups(int[] amount) {Arrays.sort(amount);int a = amount[0], b = amount[1], c = amount[2];if (a + b <= c) return c;return (a + b - c + 1) / 2 + c;}
}

http://www.ppmy.cn/embedded/15239.html

相关文章

Java-GUI-AWT-组件-TextComponent类

1 需求 2 接口 java.lang.Object java.awt.Component java.awt.TextComponent Method Detail public void setText(String t)public String getText()public String getSelectedText()public boolean isEditable()public void setEditable(boole…

机器学习在基因组学中的应用

机器学习在基因组学中的应用 李升伟1 茅 矛1 陈 竺2 &#xff08;1.特趣生物科技有限公司&#xff0c;广东省深圳市&#xff1b;2.上海交通大学医学院附属瑞金医院&#xff0c;上海市&#xff09; 机器学习在基因组学中的应用已经变得日益重要和普遍&#xff0c;其核心价…

jsp实验11 JavaBean

二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握javabean的用法。【参考课本 上机实验 5.5.2 】 三、源代码以及执行结果截图&#xff1a; 源代码&#xff1a; Memory.java package sea.water; import java.util.ArrayList; import java.util…

数据结构练习-算法与时间复杂度

----------------------------------------------------------------------------------------------------------------------------- 1. 设n是描述问题规模的非负整数&#xff0c;下列程序段的时间复杂度是( )。 x0;while(n>(x1)*(x1)xx1; A.O(logn) B.O(n^(1/2)) C.O(n)…

算法新手(一)——位运算、算法是什么、介绍位运算和简单排序

一、二进制、位运算 java中int最大值&#xff0c;2的31次方-1&#xff0c;为什么不是2的32次方-1&#xff1f; ——因为第一位是符号位&#xff0c;0表示正数&#xff0c;1表示复数&#xff1b; 1.1 Integer二进制 -1的二进制&#xff1a; 11111111111111111111111111111111…

Visual Studio调试C/C++指南

1. 前言 Visual Studio&#xff08;VS&#xff09;是微软开发的一款集成开发环境(IDE)软件&#xff0c;支持C/C、C#、VB、Python等开发语言&#xff0c;开发桌面、Web等应用程序。VS功能极其强大&#xff0c;使用极其便利&#xff0c;用户数量最多&#xff0c;被誉为"宇宙…

网络安全学习路线推荐

基础阶段&#xff1a; 网络安全行业与法规 Linux操作系统 计算机网络基础&#xff08;ARP TCP HTTP等是重点&#xff09; HTML MySQL基础 PHP Python 重点学习阶段&#xff1a; 理解原理能够复现掌握挖掘方式掌握工具使用掌握修复方式 渗透&#xff1a; 漏洞原理 各种漏洞的…

MyBatis Dynamic SQL基本使用

MyBatis Dynamic SQL基本使用 一、概念二、特性Hamcrest是什么 三、MyBatis Dynamic SQL 快速入门3.1 环境准备3.2 定义表和列3.3 创建 MyBatis3 映射器3.4 使用 MyBatis3 执行 SQL 四、数据库对象表示4.1 表或视图表示4.2 表别名4.3 列表示 五、Where 子句支持5.1 简单的 wher…