[LeetCode] 1352. Product of the Last K Numbers

Implement the class ProductOfNumbers that supports two methods:

1. add(int num)

  • Adds the number num to the back of the current list of numbers.

2. getProduct(int k)

  • Returns the product of the last k numbers in the current list.
  • You can assume that always the current list has at least k numbers.

At any time, the product of any contiguous sequence of numbers will fit into a single 32-bit integer without overflowing.

Example:

Input
["ProductOfNumbers","add","add","add","add","add","getProduct","getProduct","getProduct","add","getProduct"]
[[],[3],[0],[2],[5],[4],[2],[3],[4],[8],[2]]

Output
[null,null,null,null,null,null,20,40,0,null,32]

Explanation
ProductOfNumbers productOfNumbers = new ProductOfNumbers();
productOfNumbers.add(3);        // [3]
productOfNumbers.add(0);        // [3,0]
productOfNumbers.add(2);        // [3,0,2]
productOfNumbers.add(5);        // [3,0,2,5]
productOfNumbers.add(4);        // [3,0,2,5,4]
productOfNumbers.getProduct(2); // return 20. The product of the last 2 numbers is 5 * 4 = 20
productOfNumbers.getProduct(3); // return 40. The product of the last 3 numbers is 2 * 5 * 4 = 40
productOfNumbers.getProduct(4); // return 0. The product of the last 4 numbers is 0 * 2 * 5 * 4 = 0
productOfNumbers.add(8);        // [3,0,2,5,4,8]
productOfNumbers.getProduct(2); // return 32. The product of the last 2 numbers is 4 * 8 = 32 

Constraints:

  • There will be at most 40000 operations considering both add and getProduct.
  • 0 <= num <= 100
  • 1 <= k <= 40000

最后 K 个数的乘积。

请你实现一个「数字乘积类」ProductOfNumbers,要求支持下述两种方法:

1. add(int num)

将数字 num 添加到当前数字列表的最后面。
2. getProduct(int k)

返回当前数字列表中,最后 k 个数字的乘积。
你可以假设当前列表中始终 至少 包含 k 个数字。
题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/product-of-the-last-k-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是用一个list保存遍历到的所有数字的前缀和。首先我们需要在list中添加一个1,这样在计算乘积的时候,一开始加进去的数字才有东西可以相乘。

对于 add() 函数而言,因为被添加的数字一定大于等于0,所以分两种情况

  • 如果num大于0,则计算前缀和,并把前缀和添加到list中
  • 如果num == 0,那么计算的前缀和是0。此时我们可以抛弃之前存储的所有前缀和并且重新写一个空的list。为什么可以这样做呢?因为如果当你要取的最后 k 个数字会包含这个0的话,他们的乘积也一定是0;如果当你要取的最后 k 个数字不包含这个0的话,在前缀和list中位于0左侧的数字其实也是没有意义的,因为他们不会参与最后结果的计算

对于 getProduct() 函数,我举例说明。比如input给了[3, 2, 5, 6, 4],那么前缀和list会是list = {3, 6, 30, 180, 720}, list.size() == 5。此时如果k == 2,那么res = list.get(5 - 1) / list.get(5 - 1 - 2) = list.get(4) / list.get(2) = 720 / 30 = 24。这个规律不难找,多找几个例子试一下就可以写出代码了。

时间,add() - O(1), getProduct - O(1)

空间O(n)

Java实现

 1 class ProductOfNumbers {
 2     List<Integer> list;
 3     
 4     public ProductOfNumbers() {
 5         list = new ArrayList<>();
 6         list.add(1);
 7     }
 8     
 9     public void add(int num) {
10         if (num > 0) {
11             list.add(list.get(list.size() - 1) * num);
12         } else {
13             list = new ArrayList<>();
14             list.add(1);
15         }
16     }
17     
18     public int getProduct(int k) {
19         int len = list.size();
20         if (k < len) {
21             return list.get(len - 1) / list.get(len - 1 - k);
22         } else {
23             return 0;
24         }
25     }
26 }
27 
28 /**
29  * Your ProductOfNumbers object will be instantiated and called as such:
30  * ProductOfNumbers obj = new ProductOfNumbers();
31  * obj.add(num);
32  * int param_2 = obj.getProduct(k);
33  */

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14202553.html