两个数组a[N],b[N],其中a[N]的各个元素值已知,现给b[i]赋值

问题描述:两个数组a[N],b[N],其中a[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]...*a[N-1]/a[i];
要求:
1.不准用除法运算
2.除了循环计数值,a[N],b[N]外,不准再用其他任何变量(包括局部变量,全局变量等)

3.满足时间复杂度O(n),空间复杂度O(1)


算法实现:

[cpp]  view plain copy
  1. int main(int argc, char* argv[])  
  2. {  
  3.     int i;  
  4.     int a[10] = {1, 2, 1, 2, 1, 2, 1, 2, 1, 2};  
  5.     int b[10];  
  6.       
  7.     b[0] = 1;  
  8.     for(i = 1; i < 10; i++)  
  9.     {  
  10.         b[0] *= a[i - 1];  
  11.         b[i] = b[0];  
  12.     }  
  13.     b[0] = 1;  
  14.     for(i = 8; i > 0; i--)  
  15.     {  
  16.         b[0] *= a[i + 1];  
  17.         b[i] *= b[0];  
  18.     }  
  19.     b[0] *= a[1];//<span style="color:#cc0000;">注意下这个地方</span>  
  20.       
  21.     for(i = 0; i < 10; i++)  
  22.     {  
  23.         cout << b[i] << " ";  
  24.     }  
  25.     cout << endl;  
  26.       
  27.     return 0;  
  28. }  


类似有一道题

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)的时间内计算。

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

[cpp]  view plain copy
  1. #include <iomanip>  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. void show(int v[], int n, char const * name)  
  6. {  
  7.   cout << name << ": ";  
  8.   for(int i = 0; i < n; ++i){  
  9.     cout << setw(7) << v[i];  
  10.   }  
  11.   cout << '\n';  
  12. }  
  13.   
  14. int main()  
  15. {  
  16.   int a[] = {2, 3, 5, 7, 11}; // 用质数测试保证每个积都唯一。  
  17.   int const N = sizeof(a) / sizeof(a[0]);  
  18.   
  19.   int prod_fore[N];  
  20.   int prod_back[N];  
  21.   prod_fore[0  ] = 1;  
  22.   prod_back[N-1] = 1;  
  23.   
  24.   for(int i = 1; i < N; ++i){  
  25.     prod_fore[i] = a[i-1] * prod_fore[i-1];  
  26.   }  
  27.   
  28.   for(int i = N-2; i >= 0; --i){  
  29.     prod_back[i] = a[i+1] * prod_back[i+1];  
  30.   }  
  31.   
  32.   show(a        , N, "source   ");  
  33.   
  34.   for(int i = 0; i < N; ++i){  
  35.     a[i] = prod_fore[i] * prod_back[i];  
  36.   }  
  37.   
  38.   show(prod_fore, N, "prod_fore");  
  39.   show(prod_back, N, "prod_back");  
  40.   show(a        , N, "result   ");  
  41. }  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值