45 最大子数组差

原题网址:https://www.lintcode.com/problem/maximum-subarray-difference/description

描述

给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大。

返回这个最大的差值。

子数组最少包含一个数

您在真实的面试中是否遇到过这个题?  是

样例

给出数组[1, 2, -3, 1],返回 6

挑战

时间复杂度为O(n),空间复杂度为O(n)

思路:两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大,即是说其中一个最大,另一个最小。

顺着最大子数组Ⅱ的解法,定义四个数组leftMax,leftMin,rightMax,rightMin,分别保存0~i的最大子数组和、最小子数组和以及i+1~n-1的最大子数组和、最小子数组和;

遍历,计算leftMax - rightMin 与 rightMax - leftMin 的最大值,将两者中较大的一个return出去。

AC代码:

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer indicate the value of maximum difference between two substrings
     */
    int maxDiffSubArrays(vector<int> &nums) {
        // write your code here
        int n=nums.size();
     if (n==0)
     {
         return 0;
     }
     vector<int> leftMax(n,0);
     vector<int> leftMin(n,0);
     vector<int> rightMax(n,0);
     vector<int> rightMin(n,0);
     int i=0,tempsum1,tempsum2,maxsum,minsum;

     leftMax[0]=leftMin[0]=maxsum=minsum=nums[0];
     tempsum1=tempsum2=0;
     for (i=0;i<n;i++)
     {
         tempsum1+=nums[i];
         tempsum2+=nums[i];
         if (tempsum1>maxsum)
         {
             maxsum=tempsum1;
         }
         if (tempsum1<0)
         {
             tempsum1=0;
         }
         if (tempsum2<minsum)
         {
             minsum=tempsum2;
         }
         if (tempsum2>0)
         {
             tempsum2=0;
         }
         leftMax[i]=maxsum;
         leftMin[i]=minsum;
     }

     rightMax[n-1]=rightMin[n-1]=maxsum=minsum=nums[n-1];
     tempsum1=tempsum2=0;

     for (i=n-1;i>0;i--)
     {
         tempsum1+=nums[i];
         tempsum2+=nums[i];
         if (tempsum1>maxsum)
         {
             maxsum=tempsum1;
         }
         if (tempsum1<0)
         {
             tempsum1=0;
         }
         if (tempsum2<minsum)
         {
             minsum=tempsum2;
         }
         if (tempsum2>0)
         {
             tempsum2=0;
         }
         rightMax[i-1]=maxsum;
         rightMin[i-1]=minsum;
     }

     int diff1=leftMax[0]-rightMin[0];
     int diff2=rightMax[0]-leftMin[0];
     for (i=1;i<n-1;i++)
     {
         if (leftMax[i]-rightMin[i]>diff1)
         {
             diff1=leftMax[i]-rightMin[i];
         }
         if (rightMax[i]-leftMin[i]>diff2)
         {
             diff2=rightMax[i]-leftMin[i];
         }
     }
     int diff=max(diff1,diff2);
     return diff;
    }
};

原文地址:https://www.cnblogs.com/Tang-tangt/p/9085570.html

时间: 2024-11-06 08:58:12

45 最大子数组差的相关文章

lintcode 中等题:maximum subarray difference 最大子数组差

题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1],返回 6 注意 子数组最少包含一个数 挑战 时间复杂度为O(n),空间复杂度为O(n) 解题 刚做了数组中两个子数组和的最大值,这一题是求差,感觉上题的求解思想应该是可以用的 A B 分别是两个子数组的和,则: 所以 当A>B 的时候A越大越好 B越小越好 当A<B 的时候B越大越好 A越小越好

LintCode-最大子数组差

给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[1, 2, -3, 1],返回 6 注意 子数组最少包含一个数 挑战 时间复杂度为O(n),空间复杂度为O(n) 标签 Expand 相关题目 Expand 分析:这题还是有点难度的感觉,首先直觉是可以套用求最大字数组和的代码,其次,求差的绝对值最大,那么求出子数组和的最大最小值,然后相减就行,但是有

结对开发——返回整数数组最大子数组和2

返回整数数组最大子数组和2 为了实现“敏捷开发”的目的,老师让我们采取“迭代”的方法进行项目的开发,这不,对于周一的求最大子数组和又有了新的要求,如下: 1.延续上次的要求,这里不再赘余… 2.如果数组A[0]……A[j-1]首尾相连,允许A[i-1],……A[n-1],A[0]……A[j-1]之和最大: 3.同时返回最大子数组的位置: 4.要求程序必须能处理1000 个元素,且每个元素是int32 类型的. 一.实验设计思路 首先实现的是数组首尾相连,先存入数组,再将原数组反向存储形成环形数组

一维数组头尾相连求最大子数组

题目: 返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 1. 设计思想: 因为已经写过了一维数组的求最大子数组程序.所以只是在原程序上进行修改.首先产生随机数数组,然后进行计算,因为要求时间复杂度

二维数组中最大子数组的和

题目:返回一个二维整数数组中最大子数组的和. 要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 思路: 借鉴网上代码整理得思路: 根据一位数组最大子数组求和的编程思路,讲二维数组转化成一维数组求解: 即求出每一行的最大子数组之和,通过比较各行最大子数组之和的大小,求出只有二维数组只有一行的情况下的最大子数组之和: 然后求每两行最大子数组之和,即将每两行的相同列相加,将二维数

3、软件工程结对开发之求一维数组中连续最大子数组之和并判断溢出

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 要求程序必须能处理1000 个元素: 每个元素是int32 类型的: 输入一个整形数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为O(n): 结果溢出之后能判断. 二.设计思想 在我们的前一个程序中,由于int类型rand()随机产生数范围是0~32767,所以产生的1000个数较小,不会产生溢出.但我们通过查资料得知int32最大数是2147

一维回环数组求解最大子数组问题

一.题目与要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n) 二.设计思想 通过上次求解简单一维数组的最大子数组问题的解决,我们找到了一种实现时间复杂为O(n)的方法,采用的是二分法和递归

最大子数组

/*求子数组的最大和题目描述:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18.*/ 1 #include<stdio.h> 2 typedef struct addelem{ 3 int low; 4 int high; 5 int max;

最大子数组和(最大子段和)

比如对于数组[1,-2,3,5,-1,2] 最大子数组和是sum[3,5,-1,2] = 9, 我们要求函数输出子数组和的最大值,并且返回子数组的左右边界(下面函数的left和right参数). 本文我们规定当数组中所有数都小于0时,返回数组中最大的数(也可以规定返回0,只要让以下代码中maxsum初始化为0即可,此时我们要注意-1 0 0 0 -2这种情形,特别是如果要求输出子数组的起始位置时,如果是面试就要和面试官问清楚) 以下代码我们在PAT 1007. Maximum Subsequen