剑指offer66题解法之上下三角分区

先上第一次通过的代码

// class Solution {
// public:
//     vector<int> constructArr(vector<int>& a) {
//         vector<int> b(a.size(),1);
//         for(int i=0;i<a.size();++i){    //O(n^2),测试过了,但还是时间复杂度太高,怎么优化?不让用除法,确实
//         //如果拿积合除以a[i]那就太容易了,有没有不用除法但可以这么简单的方法?
//         //分区间?多大的区间合适?
//         //
//             for(int j=0;j<a.size();++j){
//                 if(j!=i){
//                     b[i]*=a[j];
//                 }
//             }
//         }
//         return b;
//     }
// };

//分区,用上下三角分成两个区,时间复杂度从n方掉到n
class Solution {
public:
    vector<int> constructArr(vector<int>& a) {

        vector<int> b(a.size(),1),tmp(a.size(),1);

        //vector<int> b,tmp;    //用这个两行的程序代替上面的一行程序就会报错,问题出在哪?对角线上元素的初始化?
        //b[0]=1;tmp[a.size()-1]=1;

        //for(int i=0;i<a.size();++i){//这里给对角线元素初始化为1了,还是报错
        //    b[i]=1;                 
        //    tmp[i]=1;                 //暂时想不明白为什么只给b和tmp的对角线初始化会报错,走流程应该不会出现越界啊
        //}

        for(int i=1;i<a.size();++i){
            b[i]=b[i-1]*a[i-1];
        }
        for(int j=a.size()-2;j>=0;--j){
            tmp[j]=a[j+1]*tmp[j+1];
        }
        for(int i=0;i<a.size();++i){
            b[i]*=tmp[i];
        }
        return b;
    }
};

 我最想不明白的是对于b数组的初始化,按照步骤走应该只需要给b[0]初始化就足够了啊

先看可以优化的点,tmp数组是多余的,只要一个变量tmp就可以搞定,不仅用单数组还能省去一个for循环

优化后写法

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {
        int n = a.size();
        // 返回结果的计算
        vector<int> b(n, 1);
        // 从上到下,左下角的遍历
        for (int i = 1; i < n; ++i)
        {
            b[i] *= b[i-1] * a[i-1];
        }

        
        int accu = 1; // 累计乘积的结果,用于和b[i] 来计算
        // 从下到上,左上角的遍历
        for (int i = n-2; i >=0 ; --i)
        {
            accu *= a[i+1];
            b[i] *= accu;
        }

        return b;
    }
};

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值