题目🎊
编程梦想家(大学生版)-CSDN博客
桌上有
n
堆力扣币,每堆的数量保存在数组coins
中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。
❤ 这个问题实际上是一个贪心算法的应用。给定的问题可以这样理解:你面前有若干堆硬币,每堆有不同数量的硬币,你的任务是用最少的次数拿完所有的硬币。规则是每次可以从任意一堆中拿走1枚或者2枚硬币。
☎题解:
class Count{
public int minCount(int[] coins) {
int sum = 0;
for (int i : coins) {
sum += (i + 1) / 2;
}
return sum;
}
}
Count类中的minCount
方法就是用来解决这个问题的。下面是这个方法的逻辑分析:
首先,方法接收一个整数数组
coins
作为参数,该数组表示每堆硬币的数量。定义一个整数
sum
用来记录拿硬币的总次数,初始值为0。遍历数组
coins
中的每个元素(即每堆硬币的数量),对于每个元素i
:
- 由于每堆硬币可以拿走1枚或者2枚,因此拿走这堆硬币最少需要的次数是
(i + 1) / 2
。这里加1是因为即使是最后一枚硬币,也算作一次拿取动作。- 然后,将这个次数加到
sum
上。最后,返回
sum
作为拿完所有硬币的最少次数。
🎁 为什么这是一个贪心算法呢?贪心算法在每一步选择中都采取当前状态下最好的选择,从而希望导致结果是全局最优的。在这个问题中,贪心策略是每次尽可能多地拿走硬币(在本例中是每次拿2枚),如果硬币数量是奇数,则最后必然剩下1枚硬币需要单独拿走。
🎀 这个算法之所以有效,是因为它保证了不会因为先拿小堆的硬币而导致最后剩下很多单独的硬币需要多次拿走。由于每堆硬币都可以独立地拿走1枚或2枚,所以算法保证了最少的拿取次数。
举个例子,如果coins
数组是[3, 2, 7]
,那么按照这个算法:
- 第一堆拿2次(拿走2枚和1枚)
- 第二堆拿1次(拿走2枚)
- 第三堆拿4次(拿走2枚,重复2次)
总共需要拿7次,这是最少的次数。
🎗Junit测试用例示例如下:
@Test
public void test() {
assert(Count.minCount(new int[]{3, 2, 7}) == 7);
}
ss