具有插入和最后K元素乘积操作的数据结构(附代码示例)

在这篇文章中,我们介绍了2种数据结构的设计,包括插入和最后K元素的乘积操作。这两种操作都可以在恒定的O(1)时间内完成。

目录:

  1. 问题陈述
  2. 新数据结构的天真方法
  3. 新数据结构的最佳解决方案

要练习更多类似的数据结构设计问题,请阅读这篇文章

先决条件。前缀和数组

让我们从数据结构的插入和最后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 个元素的积。
    • 返回计算出的乘积

代码

#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 元素的乘积或者最后一个滑动窗口大小的乘积kproduct 我们只需要将滑动窗口可视化,对于计算最后一个滑动窗口的乘积,我们只需要用multiply newly inserted element ,对于去除最后一个元素的贡献,我们只需要用divide productelement which we have to remove from sliding window

例如:让k=2 (滑动窗口的大小)或我们的数据结构,我们想插入4个元素 :

  1. 在DS中插入a ,然后插入product = acontainer = [a]
  2. 在ds中插入b ,然后插入product = a*bcontainer = [(a b)]
  3. 在ds中插入c ,然后插入product = (a*b*c)/a= b*ccontainer = [a (b c)]
  4. 在ds中插入d ,然后插入product = (b*c*d)/b= c*dcontainer = [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元素的乘积操作有了完整的了解。

猜你喜欢

转载自juejin.im/post/7125726645298102308