【java-算法】连续数组最大和

来源:互联网 发布:小米笔记本 显卡知乎 编辑:程序博客网 时间:2024/06/06 14:12
import java.util.*;/** * HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。 * 今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。 * 但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢? * 例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。 * 你会不会被他忽悠住?(子向量的长度至少是1) * Created by ZeHua on 2017/5/29. */public class FindGreatestSumOfSubArray {    public int FindGreatestSumOfSubArray(int[] array) {        if(array==null||array.length==0){            return 0;        }        if(array.length==1){            return array[0];        }        //构建最大和数组        int[] sum = new int[array.length];        for(int i=0,sum_i=0;i<array.length;i++ ){            sum_i=sum_i+array[i];            sum[i]=sum_i;        }        MaxSumQueue queue = new MaxSumQueue(sum);        //开头到末尾的窗口最大值的特殊队列        for(int i=0;i<sum.length;i++){            queue.add(i);        }        int res;        //窗口左端逐步右移,找出子向量的最大和        res = sum[queue.peek()];        if(queue.peek()==0){            queue.poll();        }        for(int i=0;i<sum.length-1;i++){            int max = sum[queue.peek()];            int cur = max - sum[i];            if(cur>res){                res=cur;            }            if(queue.peek()==i+1){                queue.poll();            }        }        return res;    }    public static void main(String[] args) {        int array[]={1,-2,3,10,-4,7,2,-5};        int max = new FindGreatestSumOfSubArray().FindGreatestSumOfSubArray(array);        System.out.println(max);    }}//保存窗口最大值的特殊队列class MaxSumQueue{    LinkedList<Integer> queue = new LinkedList<>();    int sum[];    public MaxSumQueue(int[] sum){        this.sum=sum;    }    public void add(int index){        while(true){            if(queue.isEmpty()){                queue.addLast(index);//下标入队                return;            }else{                if(sum[queue.peekLast()]>sum[index]){//比较的是值                    queue.addLast(index);//下标入队                    return;                }            }            queue.pollLast();        }    }    public int peek(){        if(queue.isEmpty()){            throw new RuntimeException("队列为空");        }        return queue.peekFirst();    }    public int poll(){        if(queue.isEmpty()){            throw new RuntimeException("队列为空");        }        return queue.pollFirst();    }}