惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
博客园 - 【当耐特】
阮一峰的网络日志
阮一峰的网络日志
The Cloudflare Blog
N
Netflix TechBlog - Medium
P
Privacy International News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
G
Google Developers Blog
Recorded Future
Recorded Future
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
B
Blog RSS Feed
G
GRAHAM CLULEY
A
Arctic Wolf
N
News | PayPal Newsroom
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Register - Security
The Register - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
V
Visual Studio Blog
Webroot Blog
Webroot Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
H
Heimdal Security Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
M
MIT News - Artificial intelligence
V2EX - 技术
V2EX - 技术
Jina AI
Jina AI
TaoSecurity Blog
TaoSecurity Blog
NISL@THU
NISL@THU
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
WordPress大学
WordPress大学
V
V2EX
Cyberwarzone
Cyberwarzone
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - Grandyang

[LeetCode] 1372. Longest ZigZag Path in a Binary Tree 二叉树中的最长交错路径 [LeetCode] 1371. Find the Longest Substring Containing Vowels in Even Counts 每个元音包含偶数次的最长子字符串 [LeetCode] 1370. Increasing Decreasing String 上升下降字符串 [LeetCode] 1368. Minimum Cost to Make at Least One Valid Path in a Grid 使网格图至少有一条有效路径的最小代价 [LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表 [LeetCode] 1366. Rank Teams by Votes 通过投票对团队排名 [LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字 [LeetCode] 1363. Largest Multiple of Three 形成三的最大倍数 [LeetCode] 1362. Closest Divisors 最接近的因数 [LeetCode] 1361. Validate Binary Tree Nodes 验证二叉树 [LeetCode] 1360. Number of Days Between Two Dates 日期之间隔几天 [LeetCode] 1359. Count All Valid Pickup and Delivery Options 有效的快递序列数目 [LeetCode] 1358. Number of Substrings Containing All Three Characters 包含所有三种字符的子字符串数目 [LeetCode] 1357. Apply Discount Every n Orders 每隔n个顾客打折 [LeetCode] 1356. Sort Integers by The Number of 1 Bits 根据数字二进制下1 的数目排序 [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组 [LeetCode] 1353. Maximum Number of Events That Can Be Attended 最多可以参加的会议数目 [LeetCode] 1351. Count Negative Numbers in a Sorted Matrix 统计有序矩阵中的负数 [LeetCode] 1349. Maximum Students Taking Exam 参加考试的最大学生数
[LeetCode] 1352. Product of the Last K Numbers 最后 K 个数的乘积
Grandyang · 2023-09-14 · via 博客园 - Grandyang

Design an algorithm that accepts a stream of integers and retrieves the product of the last k integers of the stream.

Implement the ProductOfNumbers class:

  • ProductOfNumbers() Initializes the object with an empty stream.
  • void add(int num) Appends the integer num to the stream.
  • int 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.

The test cases are generated so that, 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:

  • 0 <= num <= 100
  • 1 <= k <= 4 * 104
  • At most 4 * 104 calls will be made to add and getProduct.
  • The product of the stream at any point in time will fit in a 32-bit integer.

这道题给了一个数据流,让返回最后k个数字的乘积,这里博主也尝试了最简单粗暴的解法,居然没有超时,可以通过。使用一个数组 data 来记录数据流,当调用 add 函数时,将数字加入 data 中。在 getProduct 函数中,遍历末尾k个数字,将它们乘起来返回即可,参见代码如下:

解法一:

class ProductOfNumbers {
public:
    ProductOfNumbers() {}
    
    void add(int num) {
        data.push_back(num);
    }
    
    int getProduct(int k) {
        int n = data.size(), res = 1;
        for (int i = 0; i < k; ++i) {
            res *= data[n - 1 - i];
        }
        return res;
    }

private:
    vector<int> data;
};

我们也可以在上面的解法上稍微做一些优化,这里的优化思路就是快速判断若数组末尾k个数字中有0存在的话,就马上返回0,而不用再计算k个数字的乘积。这里需要记录数组中所有0出现的位置,这里使用另外一个数组 zeros 来记录所有0的位置,在 add 函数中,判断若 num 为0,则用当前 data 数组的大小来当作0的位置,加入到 zeros 数组中,然后还是要将 num 加入到 data 中。在 getProduct 函数中,首先判断末尾k个数字中是否有0,最有可能出现在末尾k个数字中的0就是 zeros 数组中的最后一个位置,判断方法是用 zeros 数组的最后一个数组(若存在的话)和 n - k 相比较,若其大于等于 n - k,直接返回0。否则还是老老实实的将末尾k个数字相乘吧,参见代码如下:

解法二:

class ProductOfNumbers {
public:
    ProductOfNumbers() {}
    
    void add(int num) {
        if (num == 0) {
            zeros.push_back(data.size());
        }
        data.push_back(num);
    }
    
    int getProduct(int k) {
        int n = data.size(), res = 1;
        if (zeros.size() != 0 && zeros.back() >= n - k) return 0;
        for (int i = 0; i < k; ++i) {
            res *= data[n - 1 - i];
        }
        return res;
    }

private:
    vector<int> data, zeros;
};

再来看一种极大优化运行时间的解法,这里创建一个累加积数组 prod,其中 prod[i] 表示末尾 n-i 个数字的乘积,则末尾k个数字的乘积为 prod[n-k]。更新 prod 数组的方法是,每当进来一个数字 num 时,prod 数组新加一个1,然后对此时 prod 数组中每个数字都乘以 num,做个小优化,当 num 为1时,不需要乘,最后返回 prod[n-k] 即可,参见代码如下:

解法三:

class ProductOfNumbers {
 public:
     ProductOfNumbers() {}
    
     void add(int num) {
         prod.push_back(1);
         if (num == 1) return;
         for (int &a : prod) a *= num;
     }
    
     int getProduct(int k) {
         return prod[(int)prod.size() - k];
     }
    
 private:
     vector<int> prod;
 };

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1352

参考资料:

https://leetcode.com/problems/product-of-the-last-k-numbers/

https://leetcode.com/problems/product-of-the-last-k-numbers/solutions/510265/c-prefix-array/

https://leetcode.com/problems/product-of-the-last-k-numbers/solutions/510260/java-c-python-prefix-product/

LeetCode All in One 题目讲解汇总(持续更新中...)