“数组a,长度为n(索引为0至n-1)。现要求更新数组的各个元素,使新数组的第i个元素等于原数组中除第i个元素之外各元素之积。”

问题:“数组a,长度为n(索引为0至n-1)。现要求更新数组的各个元素,使新数组的第i个元素等于原数组中除第i个元素之外各元素之积。即:

a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,……a[n-1]为a[0]到a[n-2]的积。要求:具有线性复杂度。不能使用除法运算符。”

讨论:最后两项要求恰好排除了最直观的两种方法"两层循环乘法"、“求全部元素的积P,然后New[i] = P / Old[i]”,卡死了思路,完全没想出来难过

后来参考了 帖子  16楼 qq120848369 的答案才明白。(第一次还没看懂,跳过去了尴尬

倒推出解题思路:新数组每个元素都是前、后两段“部分积”相乘的结果。前方的部分积很容易想到用数组保存结果,在O(n)的时间内计算。

关键是后方的部分积也可以同样算出,只是要反向累乘。逆向思维……

#include <iomanip>
#include <iostream>
using namespace std;

void show(int v[], int n, char const * name)
{
  cout << name << ": ";
  for(int i = 0; i < n; ++i){
    cout << setw(7) << v[i];
  }
  cout << '\n';
}

int main()
{
  int a[] = {2, 3, 5, 7, 11}; // 用质数测试保证每个积都唯一。
  int const N = sizeof(a) / sizeof(a[0]);

  int prod_fore[N];
  int prod_back[N];
  prod_fore[0  ] = 1;
  prod_back[N-1] = 1;

  for(int i = 1; i < N; ++i){
    prod_fore[i] = a[i-1] * prod_fore[i-1];
  }

  for(int i = N-2; i >= 0; --i){
    prod_back[i] = a[i+1] * prod_back[i+1];
  }

  show(a        , N, "source   ");

  for(int i = 0; i < N; ++i){
    a[i] = prod_fore[i] * prod_back[i];
  }

  show(prod_fore, N, "prod_fore");
  show(prod_back, N, "prod_back");
  show(a        , N, "result   ");
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值