在这篇文章中,我们介绍了2种数据结构的设计,包括插入和最后K元素的乘积操作。这两种操作都可以在恒定的O(1)时间内完成。
目录:
- 问题陈述
- 新数据结构的天真方法
- 新数据结构的最佳解决方案
要练习更多类似的数据结构设计问题,请阅读这篇文章。
先决条件。前缀和数组
让我们从数据结构的插入和最后K元素的乘积操作开始。
问题说明
我们必须设计一个支持以下操作的数据结构:
- Insert:在数据结构中插入一个新元素E。
- ProductK:返回最后插入的K个元素的乘积。
给定的输入列表为:[1, 2, 3, 4, 5, 6]
,而k
的值为3
因此,最后k=3
元素的乘积是: result = 4 * 5 * 6 = 120
新数据结构的天真方法
在这种方法中,我们将使用简单的矢量来存储列表。该结构将是这样的:
class data_structure{
vector<double> a;
int k;
}
复制代码
我们将创建两个函数insert(x)
来添加元素,product_of_k_ele()
来返回最后的k
的元素。
insert(int x)
- 这将只是在向量中添加元素
- 时间复杂度。
O(1)
product_of_k_ele()
- 这将通过遍历最后的k个元素来计算最后k个元素的乘积。
- 时间复杂度。
O(K)
伪装代码
- 声明空容器和两个变量用于存储值
k
. - 定义函数
insert(x)
- 在最后一个元素中插入元素
x
- 在最后一个元素中插入元素
- 定义函数
product_of_k_ele()
- 通过使用线性遍历将最后的k个元素相乘来计算最后
k
个元素的积。 - 返回计算出的乘积
- 通过使用线性遍历将最后的k个元素相乘来计算最后
代码
#include<iostream>
#include<vector>
using namespace std;
class data_structure{
vector<double> a;
int k;
public:
// constructor for declaring variable k
data_structure(int x){
k=x;
}
// function for inserting elements in data structure
void insert(double x){
a.push_back(x);
}
// function for fetching product of last k elements
double product_of_k_ele(){
double product=1;
for(int i=a.size()-k; i<a.size(); i++) product*=a[i];
return product;
}
};
void solve()
{
// n = no of element data structure, k number of element from end
int n, k; cin>>n>>k;
data_structure ds(k);
int temp;
for(int i=1; i<=n; i++){
cin>>temp;
// inserting n elements in data structure
ds.insert((double) temp);
}
cout<<ds.product_of_k_ele()<<endl;
}
int main() {
solve();
return 0;
}
复制代码
新数据结构的最佳解决方案
这里使用的技术是滑动窗口技术,我们将从列表的末尾抽取大小为k
的窗口并返回该滑动窗口内所有元素的乘积。
在这里,我们使用了矢量来使容器具有灵活性和良好的索引:
- 由于我们的目的是获得最后k个元素的乘积,我们创建了两个函数
insert(x)
,将元素x
添加到我们的数据结构中,并计算元素k
的乘积,product_of_k_ele()
。return product of last k elements
insert(x)
函数,首先我们将在我们的容器中插入元素,直到向量的大小小于 ,我们将只是与我们插入的元素相乘的积。k
- 当容器的大小等于
k
,那么我们的滑动窗口的大小k
,滑动窗口中的元素的乘积将被存储在product
。 - 现在,当我们的容器大小为
k
,并且我们添加了一个新的元素,那么我们需要将我们的滑动窗口向右移动1
,因为我们想要最后一个k
元素的乘积或者最后一个滑动窗口大小的乘积k
。product
我们只需要将滑动窗口可视化,对于计算最后一个滑动窗口的乘积,我们只需要用multiply newly inserted element
,对于去除最后一个元素的贡献,我们只需要用divide product
。element which we have to remove from sliding window
例如:让k=2
(滑动窗口的大小)或我们的数据结构,我们想插入4个元素 :
- 在DS中插入
a
,然后插入product = a
。container = [a]
- 在ds中插入
b
,然后插入product = a*b
。container = [(a b)]
- 在ds中插入
c
,然后插入product = (a*b*c)/a= b*c
。container = [a (b c)]
- 在ds中插入
d
,然后插入product = (b*c*d)/b= c*d
。container = [a b (c d)]
我们的结果将是c*d
Note:
()
在容器中代表滑动窗口
通过这一点我们可以清楚地看到,为了保持最后一个k
元素的乘积,使用这种技术我们可以在插入时轻松地计算出O(1)
的乘积。
我们新的数据结构的结构将是:
class data_structure {
vector<double> a;
int k;
double product;
}
复制代码
例子:
-
让给定的数组为
size = 6
的[1, 2, 3, 4, 5, 6]
,让k = 3
的值。 -
如
k = 3
,那么滑动窗口的大小也将是:3
-
现在我们将逐一插入每个元素,并与这些数字相乘,直到向量大小小于
k
-
当矢量大小为k时,我们的第一个k大小的滑动窗口将是
[1, 2, 3]
,元素的乘积将被存储在乘积变量中。因此product = 1*2*3
-
如果我们插入新的元素,那么我们新的滑动窗口将是
[2, 3, 4]
,然后在乘积中1*2*3*4
,为了消除滑动窗口中第一个元素之前的贡献,我们将用该元素除以乘积。 -
因此,产品将是
(1*2*3*4)/1 = 2*3*4
-
当我们加入下一个元素,即5
,那么新的滑动窗口=[3, 4, 5]
,产品将是2*3*4*5
,为了去除滑动窗口第一个元素之前的元素贡献,我们将用该元素除以产品。
-
因此
product = (2*3*4*5)/2 = 3*4*5
-
在插入所有元素后,我们将得到最后一个滑动窗口
[4, 5, 6]
,最后一个元素 的乘积将得到 。product = 4*5*6
-
最后一个
k
元素的乘积将被储存在 product 中,我们可以用product_of_k_ele()
函数来获取它。 -
我们只需要将滑动窗口可视化,并关注product变量,在这个变量中,我们将把最后一个滑动窗口中大小为
k
的产品元素存储在我们的容器向量中。
insert(int x)
- 这将在我们的数据结构中添加元素
x
- 时间的复杂性。
O(1)
- 同时,在插入的时候,它将计算
k
元素的乘积,这将花费O(1)
时间。
product_of_k_ele()
- 这个函数将返回最后一个
k
元素的积。 - 时间的复杂性。
O(1)
伪代码
- 声明空容器和两个变量用于存储
product of k elements
和值k
。 - 定义函数
insert(x)
- 在最后一个元素
x
中插入元素 - 计算最后一个
k
元素的乘积,并更新变量,以获得k
元素的乘积。
- 在最后一个元素
- 定义函数
product_of_k_ele()
- 返回最后一个
k
元素的乘积
- 返回最后一个
代码
// Part of iq.opengenus.org
#include<iostream>
#include<vector>
using namespace std;
class data_structure{
vector<double> a;
int k;
double product;
public:
// constructor for declaring variable k
data_structure(int x){
k=x;
}
// function for inserting elements in data structure
void insert(double x){
a.push_back(x);
if(a.size()==1) product=a[0];
else if(a.size()>k) product/=a[a.size()-k-1], product*=x;
else product*=x;
}
// function for fetching product of last k elements
double product_of_k_ele(){
return product;
}
};
void solve()
{
// n = no of element data structure, k number of element from end
int n, k; cin>>n>>k;
data_structure ds(k);
int temp;
for(int i=1; i<=n; i++){
cin>>temp;
// inserting n elements in data structure
ds.insert((double) temp);
}
cout<<ds.product_of_k_ele()<<endl;
}
int main() {
solve();
return 0;
}
复制代码
输入
6 3
1
2
3
4
5
6
复制代码
输出
120
复制代码
通过OpenGenus的这篇文章,你一定对数据结构的插入和最后K元素的乘积操作有了完整的了解。