Easy

题目描述

给你一个整数数组 prices ,它表示一家商店里各种巧克力的价格。同时给你一个整数 money ,表示你一开始拥有的钱数。

你必须购买恰好两块巧克力,并且购买后你的剩余钱数必须是非负数。你希望最小化购买两块巧克力的价格总和。

请你返回购买两块巧克力后你的剩余钱数。如果没有办法购买两块巧克力而不负债,请返回 money。注意剩余钱数必须是非负数。

示例 1:

输入:prices = [1,2,2], money = 3
输出:0
解释:分别购买价格为 1 和 2 的巧克力。购买后你还剩下 3 - 3 = 0 块钱。因此,我们返回 0。

示例 2:

输入:prices = [3,2,3], money = 3
输出:3
解释:你无法用 3 块钱购买 2 块巧克力而不负债,所以我们返回 3。

提示:

  • 2 <= prices.length <= 50
  • 1 <= prices[i] <= 100
  • 1 <= money <= 100

解题思路

这道题的核心思路是寻找价格数组中两个最小的元素,然后判断它们的和是否不超过我们拥有的钱数。

解法一:排序法(推荐) 最直观的方法是对价格数组进行排序,排序后前两个元素就是最小的两个价格。如果这两个价格的和小于等于我们的钱数,就可以购买,返回剩余钱数;否则返回原有钱数。

解法二:一次遍历法 我们也可以通过一次遍历找到最小的两个价格。维护两个变量分别存储最小值和次小值,遍历数组时动态更新这两个值。

解法三:暴力法 枚举所有可能的两个巧克力组合,找到价格和最小且不超过钱数的组合。

由于数组长度最大为50,所有方法的时间复杂度都是可接受的。排序法代码最简洁,推荐使用。

代码实现

class Solution {
public:
    int buyChoco(vector<int>& prices, int money) {
        sort(prices.begin(), prices.end());
        int minCost = prices[0] + prices[1];
        return minCost <= money ? money - minCost : money;
    }
};
class Solution:
    def buyChoco(self, prices: List[int], money: int) -> int:
        prices.sort()
        min_cost = prices[0] + prices[1]
        return money - min_cost if min_cost <= money else money
public class Solution {
    public int BuyChoco(int[] prices, int money) {
        Array.Sort(prices);
        int minCost = prices[0] + prices[1];
        return minCost <= money ? money - minCost : money;
    }
}
var buyChoco = function(prices, money) {
    prices.sort((a, b) => a - b);
    const minCost = prices[0] + prices[1];
    return minCost <= money ? money - minCost : money;
};

复杂度分析

复杂度排序法一次遍历法
时间复杂度O(n log n)O(n)
空间复杂度O(1)O(1)