剑指OFFER-连续子数组的最大和(Java)

1. 连续子数组的最大和

1.1 题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

1.2 示例1

输入

[1,-2,3,10,-4,7,2,-5]

返回值

18

1.3 核心代码实现

public class Solution {
    
    
    public int FindGreatestSumOfSubArray(int[] array) {
    
    
        int res = array[0];
        int len = array.length;
        int[] sum = new int[len];
        sum[0] = res;
        for(int i = 1; i < len; i++){
    
    
            sum[i] = Math.max(array[i], sum[i-1] + array[i]);
            res = Math.max(res, sum[i]);
        }
        return res;
    }
}

2. 数组中的逆序对

2.1 题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

2.2 输入描述

题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5

2.3 示例1

输入

[1,2,3,4,5,6,7,0]

返回值

7

2.4 核心代码实现

public class Solution {
    
    
    private int res;
    public int InversePairs(int [] array) {
    
    
        if(array == null || array.length == 0){
    
    
            return -1;
        }
        Merge_Sort(array, 0, array.length - 1);
        return res;
    }
    //先分后合,分:Merge_Sort(),合:Merge()
    private void Merge_Sort(int [] array, int start, int end){
    
    
        if(start >= end){
    
        //归并结束条件,只有一个元素
            return;
        }
        int mid = (start + end) / 2;
        Merge_Sort(array, start, mid);    //左归并
        Merge_Sort(array, mid + 1, end);    //右归并
        Merge(array, start, end, mid);    //排序统计
    }
    
    private void Merge(int [] array, int start, int end, int mid){
    
    
        int [] temp = new int [end - start +1];    //辅助数组
        int index = 0;    //相当于temp数组指针,往数组添加新元素,向后移动
        int p1 = start;    //左边数组的起点
        int p2 = mid + 1;    //右边数组的起点
        
        while(p1 <= mid && p2 <= end){
    
    
            //比较p1和p2位置的元素,将较小的元素添加到temp
            if(array[p1] <= array[p2]){
    
    
                temp[index++] = array[p1++];
            }else{
    
    
                temp[index++] = array[p2++];
                res += mid - p1 + 1;
                res %= 1000000007;
            }
        }
        //若左边全部添加到temp中后,则继续往temp添加右边
        if(p1 > mid){
    
    
            while(p2 <= end){
    
    
                temp[index++] = array[p2++];
            }
        }
        //若右边全部添加到temp中后,则继续往temp添加左边
        if(p2 > end){
    
    
            while(p1 <= mid){
    
    
                temp[index++] = array[p1++];
            }
        }
        //在原数组中用有序的值覆盖掉原来无序的值
        for(int i = 0; i < temp.length; i++){
    
    
            array[start + i] = temp[i];
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_48440312/article/details/110383102
今日推荐