在那些地方可以用二分法提高性能?

        二分法是一种常见的搜索算法。在一个长度为n的数组当中查找一个数,使用暴力查找法时间复杂度为O(n),如果使用二分搜索法,复杂度则为O(logn)。

        例如,在四数之和问题当中,使用暴力法,枚举部分的代码如下

        

for(int a = 0;a<n;a++){
    for(int b = 0;b<n;b++){
        for(int c = 0;c<n;c++){
            if(int d = 0;d<n;d++){
                if(k[a]+k[b]+k[c]+k[d]==m){
                    f = true;
                }
            }
        }
    }
}

        想要实现二分法对这个搜索程序进行改进,可以修改最内一层的循环。此时时间复杂度为O(n^3logn)

if(binary_search(m - k[a] - k[b] - k[c])){
    f = true;
}

         还可以修改最内两层的循环,使得程序的时间复杂度进一步减小到O(n^2logn)。

        内侧的循环是检查kc+kd = m-ka-kb,需要将kc+kd作为一个整体先进行排序。这部分共有n^2种可能,确切的说,去掉重复后只有n(n+1)/2个数字

void solve(){
    //枚举kc+kd,得到n^2个数字
    for(int c = 0;c < n;c++){
        for(int d= 0;d<n;d++){
            kk[c*n+d] = k[c]+k[d];
        }
    }
    //排序
    sort(kk,kk+n*n);
    bool f = false;
    for(int a = 0;a<n;a++){
        for(int b = 0;b<n;b++){
            if(binary_search(m-k[a]-k[b])){
                f = true;
            }
        }
    }

}

        关于STL当中二分查找相关函数,可以看这篇文章http://t.csdn.cn/V8kjs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值