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 bothadd
andgetProduct
. 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 */