leetcode
leetcode 1151 ~ 1200
玩筹码

玩筹码

难度:

标签:

题目描述

有 n 个筹码。第 i 个筹码的位置是 position[i] 。

我们需要把所有筹码移到同一个位置。在一步中,我们可以将第 i 个筹码的位置从 position[i] 改变为:

  • position[i] + 2 或 position[i] - 2 ,此时 cost = 0
  • position[i] + 1 或 position[i] - 1 ,此时 cost = 1

返回将所有筹码移动到同一位置上所需要的 最小代价

 

示例 1:

输入:position = [1,2,3]
输出:1
解释:第一步:将位置3的筹码移动到位置1,成本为0。
第二步:将位置2的筹码移动到位置1,成本= 1。
总成本是1。

示例 2:

输入:position = [2,2,2,3,3]
输出:2
解释:我们可以把位置3的两个筹码移到位置2。每一步的成本为1。总成本= 2。

示例 3:

输入:position = [1,1000000000]
输出:1

 

提示:

  • 1 <= position.length <= 100
  • 1 <= position[i] <= 10^9

代码结果

运行时间: 23 ms, 内存: 16.1 MB


/*
 * Problem: There are n chips. The i-th chip is at position[i].
 * We can move a chip from position[i] to position[i] + 2 or position[i] - 2 with cost = 0,
 * or to position[i] + 1 or position[i] - 1 with cost = 1.
 * Our goal is to move all chips to the same position with the minimum cost.
 * 
 * Solution:
 * - Chips on even positions can be moved to other even positions with no cost.
 * - Chips on odd positions can be moved to other odd positions with no cost.
 * - Thus, the optimal strategy is to move all chips to the even or odd position with the maximum count,
 *   and then move chips from the other group to this position with cost = 1 per chip.
 */
import java.util.Arrays;

public class Solution {
    public int minCostToMoveChips(int[] position) {
        long evenCount = Arrays.stream(position)
                               .filter(pos -> pos % 2 == 0)
                               .count();
        long oddCount = position.length - evenCount;
        return (int) Math.min(evenCount, oddCount);
    }
}

解释

方法:

该题解采用的是观察所有筹码位置的奇偶性。因为筹码位置的改变只有两种情况:移动2个单位(无成本)和移动1个单位(成本为1)。移动2个单位不改变筹码的奇偶性,因此我们只需关注将筹码移动到奇数位置或偶数位置的最小成本。通过统计所有奇数位置和偶数位置的筹码数量,我们可以确定哪种筹码更多。最终,将较少的一种筹码(无论是奇数还是偶数)移动到另一种位置将产生的成本就是答案,因为每次移动成本为1。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在算法中,你是如何确定将筹码统计为奇数位置和偶数位置的原理是什么?为什么这种分类对解决问题有效?
在问题中,筹码位置的移动规则是移动2个单位没有成本,移动1个单位有成本。由于移动2个单位不改变筹码的奇偶性(奇数位置移动2个单位仍然是奇数,偶数同理),这意味着奇数位置的筹码可以无成本地集中到任何其他奇数位置,偶数位置亦然。因此,算法中只需关注筹码在奇数位置和偶数位置的分布。这种分类有效的原因是它允许我们通过统计奇数和偶数的筹码数量来确定哪种筹码较少,从而只需最小化的成本将少数的筹码移动到多数的筹码所在位置,每移动一次成本为1。
🦆
为什么将筹码从奇数位置移动到偶数位置,或者从偶数位置移动到奇数位置的成本是1,而移动两个单位的成本是0?
这是根据题目规定的移动成本设定的。题目规定移动筹码2个单位的位置不需要任何成本,而移动1个单位需要成本1。这意味着任何筹码在数轴上的位置移动到相邻位置(如从位置3到位置4,或从位置2到位置1)需要支付成本,而移动到第二个相邻位置(如从位置3到位置5,或从位置2到位置4)则不需支付成本。由于奇数和偶数位置是交替的,从任一奇数位置到任一偶数位置或反之都需要经过一个单位的移动,因此成本为1。
🦆
在实现代码中,`Counter(i % 2 for i in position)`是用来做什么的?这里的`i % 2`表示什么意思?
`Counter(i % 2 for i in position)`是用来计算筹码在奇数位置和偶数位置的数量。这里的`i % 2`计算的是i除以2的余数,它用来判断每个位置是奇数还是偶数。如果余数为0(`i % 2 == 0`),则位置i是偶数位置;如果余数为1(`i % 2 == 1`),则位置i是奇数位置。使用这个方法,我们可以快速地分类统计所有的奇数位置和偶数位置的筹码数量,以便后续决定最小化移动成本的策略。
🦆
如果输入数组`position`中所有的筹码已经位于同一位置,算法的输出是否还是正确的?
是的,算法输出仍然是正确的。如果所有筹码已经位于同一位置,无论这个位置是奇数还是偶数,该位置的筹码数量将成为数组中的唯一值。例如,如果所有筹码都在位置3(奇数),则奇数位置的计数为筹码总数,而偶数位置的计数为0。根据算法,我们会选择将较小数量的偶数位置筹码(在这个例子中为0)移动到奇数位置,因此计算的最小成本为0,这是正确的结果,因为不需要任何移动。

相关问题