算法:请找出数组中的某个数,它的左侧数字相加之和等于右边。

算法:请找出数组中的某个数,它的左侧数字相加之和等于右边。

原 算法:请找出数组中的某个数,它的左侧数字相加之和等于右边。


摘要: 二分查找的思想在算法面试题目中的使用,阿里算法面试题目:请找出数组中的某个数,它的左侧数字相加之和等于右边。

看到这题,我的第一个想法就是从头到尾遍历数组,然后计算左边之和,右边之和,比较它们。实现看起来是这样的:

/**傻逼遍历法
 * @param array
 * @return
 */
public static int stuFind(int[] array){
    for(int i=1;i<array.length;i++){
        int totalLeft=0;
        for(int le=0;le<i;le++){
            totalLeft+=array[le];
        }
        int totalRight=0;
        for(int ri=i+1;ri<array.length;ri++){
            totalRight+=array[ri];
        }
        if(totalLeft==totalRight){
            return i;
        }
    }
    return -1;
}

既然是阿里的算法面试,当然不会这么轻易的放过你,楼上的遍历时间复杂度应该是n^2.其实还可以优化一下,反正是顺序后移,计算可以偷懒一下,当你第一次计算左边的值和右边的值以后,第二次移动,左边的值等于原先左边的值+当前位置前一个位置的值,右边的值等于原先右边的值减去当前的位置的数字的值。代码看起来是这样的:

/**傻逼遍历法二
 * @param array
 * @return
 */
public static int stuFind(int[] array){
    int totalLeft=0;
    int totalRight=0;
    for(int i=1;i<array.length;i++){
        if(i==1){
            for(int le=0;le<i;le++){
                totalLeft+=array[le];
            }
            for(int ri=i+1;ri<array.length;ri++){
                totalRight+=array[ri];
            }
        }else{
            totalLeft+=array[i-1];
            totalRight-=array[i];
        }

        if(totalLeft==totalRight){
            return i;
        }
    }
    return -1;
}

从头到尾的遍历,暂时想不出来更好的办法了,换个思路:既然某个数字的左边的值等于右边,那么可以算出数组的全部数值,然后加入一个二分查找的办法,定位到中间,如果左边的值*2=数组的和-当前位置的值,那么就可以说找到了,如果大于,那就向前移动,小于就向后移动。(为什么要左边的值*2,而不是(数组的和-当前位置的值)/2,欢迎你评论 :),算法的实现看起来是这样的:

/**
 * 二分查找法
 * @param array
 * @return
 */
public static int splitFind(int[] array) {
    if (null == array || array.length == 0) {
        return -1;
    }
    int length = array.length;

    int head, tall, index;
    head = 0;
    tall = length - 1;
    index = length / 2;
    int total = 0;
    for (int i : array) {
        total += i;
    }
    do {
        int totalLeft = 0;
        for (int le = 0; le < index; le++) {
            totalLeft += array[le];
        }
        int doubleValue=(total - array[index]);
        if (totalLeft*2 < doubleValue) {
            head=index;
            index = index + (length - index) / 2;
        } else if (totalLeft*2 > doubleValue) {
            tall=index;
            index = head + (index - head) / 2;
        } else {
            return index;
        }
    } while (index > head && index < tall);
    return -1;
}

https://my.oschina.net/fengcunhan/blog/214508

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值