编程珠玑第八章,最接近0的的子向量

看了编程珠玑第八章中的内容,后面的课后练习也是非常的有意思,有一题是这么说的,给定整数m和整数n和实数向量x[n],

请找出使总和x[i]+……+x[i+m]最接近0的整数i。

我这里先不说明怎么获取最接近0的i,我先说明如何获得与0最接近的子数组之和。

看了写网上有些人已经多出了一些解法,但是觉得它们的做法好像都有些问题。例如这位大神的做法就是有些问题的。

int approximate(int * pArry, int len)  
{  
    int * cum = 0;  
    int * realarry = new int[len + 1];  
    realarry[0] = 0;    
    cum = realarry + 1;  //cum[-1] = 0  
  
    //累计pArry[0....i]的和存放于cum[i]中  
    for (int i = 0; i < len; i++)  
    {  
        cum[i] = cum[i - 1] + pArry[i];  
    }  
    sort(cum, cum + len); //对cum排序  
    int iMin = cum[1] - cum[0];  
    for (int k = 1; k < len; k++)  
    {  
        iMin = min(iMin, cum[k] - cum[k - 1]);  //返回相邻两个元素差值最小的  
    }  
    return iMin;  
}  

式子中的cum[i]代表的是从第一个元素到该元素的累加和, 如果cum[l-1] = cum[n],那么cum[l..n]就是最接近0子向量,这里一定是0.但是,最接近0的子向量也很差不多,只要把所有的cum排序就是了,delta最小的就是了,整个算法复杂度就是排序了。他的代码中没有考虑cum[i] 直接为0的情况,显然这时候的意思是从数组的开始到该元素的累加和就是0。

他的代码对于这个example是会出错的[-1,-1,2,1,2]

其实只需要添加一行代码就可以了。

int approximate(int * pArry, int len)
    {
        int * cum = 0;
        int * realarry = new int[len + 1];
        realarry[0] = 0;
        cum = realarry + 1;  //cum[-1] = 0
        
        //累计pArry[0....i]的和存放于cum[i]中
        for (int i = 0; i < len; i++)
        {
            cum[i] = cum[i - 1] + pArry[i];
            if(cum[i]==0)
                return 0;
        }
        sort(cum, cum + len); //对cum排序
        int iMin = cum[1] - cum[0];
        for (int k = 1; k < len; k++)
        {
            iMin = min(iMin, cum[k] - cum[k - 1]);  //返回相邻两个元素差值最小的
        }  
        return iMin;  
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值