购买巧克力后的最小相对损失
难度:
标签:
题目描述
代码结果
运行时间: 618 ms, 内存: 60.6 MB
/*
* LeetCode 2819: Minimum Relative Loss After Buying Chocolates
*
* Problem: Given an array of prices of chocolates and an integer k, we need to find the minimum relative loss
* if we buy exactly k chocolates. The relative loss is defined as the difference between the maximum
* and the minimum prices of the k chocolates purchased.
*
* Approach using Java Streams:
* 1. Sort the array of prices using Streams.
* 2. Initialize the minimum loss to the highest possible value.
* 3. Iterate through the sorted array, checking the relative loss for each consecutive subarray of size k.
* 4. Update the minimum loss accordingly.
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class MinimumRelativeLossStream {
public int minRelativeLoss(int[] prices, int k) {
int[] sortedPrices = Arrays.stream(prices).sorted().toArray();
return IntStream.range(0, sortedPrices.length - k + 1)
.map(i -> sortedPrices[i + k - 1] - sortedPrices[i])
.min()
.orElse(Integer.MAX_VALUE);
}
public static void main(String[] args) {
MinimumRelativeLossStream solution = new MinimumRelativeLossStream();
int[] prices = {5, 9, 1, 3, 8};
int k = 3;
System.out.println(solution.minRelativeLoss(prices, k)); // Output should be 4
}
}
解释
方法:
此题解采用前缀和与二分搜索的方法来解决问题。首先,对价格数组进行排序,以便于后续操作。接着,计算价格数组的前缀和,这有助于快速计算任意连续子数组的和。对于每个查询,首先检查是否需要所有的巧克力,如果是,则直接计算,否则使用二分搜索确定最优的购买位置以最小化损失。二分搜索寻找使得 'k-prices[mid]' 最接近 'prices[mid + need] - k' 的位置,以确保购买的巧克力价格尽可能靠近 k。最后,结合前缀和数组,计算并返回每个查询的结果。
时间复杂度:
O(n log n + q log m)
空间复杂度:
O(n + q)
代码细节讲解
🦆
为什么在处理完全需要所有巧克力的特殊情况后,算法选择使用二分搜索而不是其他搜索方法来确定最优购买位置?
▷🦆
在二分搜索中,如何确定`k - prices[mid] > prices[mid + need] - k`作为调整搜索范围的条件,这个条件有何数学或逻辑基础?
▷🦆
算法在检查是否需要所有巧克力时,直接计算了一个特定表达式`psum[x] + 2 * k * (n - x) - (psum[n] - psum[x])`,这个表达式是如何得出的,它代表了什么意义?
▷🦆
前缀和数组`psum`在本题中起到了什么作用,为何必须计算前缀和而不能直接使用原始的价格数组?
▷