价格优惠计算问题之题解
题目概述
小F在“双十一”期间购买了NN件商品。每件商品有一个价格p[i]p[i],小F可以获得的优惠取决于该商品之前的一件商品。如果某一件商品的价格p[i]p[i]大于等于前面的某个商品p[j]p[j],则小F可以享受该商品p[j]p[j]的价格作为优惠,前提是p[j]p[j]是离p[i]p[i]最近的且满足条件的商品。
- 限制是,给定价格数组
p = [9, 4, 5, 2, 4],其中p[3] = 2之前没有商品的价格小于等于p[3],因此没有优惠;而p[2] = 5可以享受最近的商品p[1] = 4的价格作为优惠。因此,任务是计算小F能获得的总优惠。 - 测试样例
样例1:
输入:
N = 5 ,p = [9, 4, 5, 2, 4]
输出:6
样例2:
输入:
N = 4 ,p = [1, 2, 3, 5]
输出:6
解题思路
-
数据结构选择
为了高效地找到最近满足条件的商品价格,可以考虑使用栈(Stack)。栈的特点是后进先出(LIFO),可以快速找到最近的满足条件的商品价格。
-
算法步骤
-
初始化:
- 初始化一个栈来存储商品价格。
- 初始化一个变量
totalDiscount来存储总优惠金额。
-
遍历商品价格数组:
- 从第一个商品开始遍历,对于每个商品,检查栈顶元素是否满足条件。
- 如果栈顶元素满足条件(即栈顶元素小于等于当前商品价格),将其弹出并累加到总优惠金额中。
- 如果栈顶元素不满足条件,继续遍历下一个商品。
-
更新栈:
在遍历过程中,将当前商品价格压入栈中。
-
返回结果:
最后返回总优惠金额。
-
时间复杂度
栈可以将查找最近的满足条件的商品价格的时间复杂度从O(N^2)优化到O(N),从而提高算法的效率。
实现代码
public class Main {
public static int solution(int N, int[] p) {
// 初始化总优惠金额
int totalDiscount = 0;
// 遍历商品价格数组
for (int i = 1; i < N; i++) {
// 检查之前的商品价格
for (int j = i - 1; j >= 0; j--) {
// 如果找到满足条件的商品价格
if (p[j] <= p[i]) {
// 更新总优惠金额
totalDiscount += p[j];
// 跳出内层循环,继续下一个商品
break;
}
}
}
// 返回总优惠金额
return totalDiscount;
}
public static void main(String[] args) {
System.out.println(solution(5, new int[]{9, 4, 5, 2, 4}) == 6);
System.out.println(solution(4, new int[]{1, 2, 3, 5}) == 6);
System.out.println(solution(4, new int[]{4, 3, 2, 1}) == 0);
}
}
输出范例
true
true
true
具体运行步骤
以样例一为例
样例1:
N = 5, p = [9, 4, 5, 2, 4]
-
初始化:
totalDiscount = 0stack = []
-
遍历商品价格数组:
-
i = 0, p[0] = 9:
- 栈为空,直接将9压入栈中。
stack = [9]
-
i = 1, p[1] = 4:
- 栈顶元素9大于4,不满足条件,直接将4压入栈中。
stack = [9, 4]
-
i = 2, p[2] = 5:
- 栈顶元素4小于等于5,弹出4并累加到
totalDiscount。 totalDiscount = 4stack = [9]- 栈顶元素9大于5,不满足条件,直接将5压入栈中。1. - -
stack = [9, 5]
- 栈顶元素4小于等于5,弹出4并累加到
-
i = 3, p[3] = 2:
- 栈顶元素5大于2,不满足条件,直接将2压入栈中。
stack = [9, 5, 2]
-
i = 4, p[4] = 4:
- 栈顶元素2小于等于4,弹出2并累加到
totalDiscount。 totalDiscount = 4 + 2 = 6stack = [9, 5]- 栈顶元素5大于4,不满足条件,直接将4压入栈中。
stack = [9, 5, 4]
- 栈顶元素2小于等于4,弹出2并累加到
-
-
返回结果:
totalDiscount = 6
写在最后的应该要注意的tips
-
栈的基本操作:
push(element):将元素压入栈顶。pop():弹出栈顶元素。peek():查看栈顶元素,但不弹出。isEmpty():检查栈是否为空。
-
栈的应用场景:
栈常用于解决需要回溯的问题,例如括号匹配、表达式求值、深度优先搜索(DFS)等。