最大连续序列和,积以及不相交数组和之差最大

问题一:子数组和的最大值:

用f[i]表示以a[i]结尾的最大连续子序列和。i在0~n-1之间,最后比较所有的f[i]找到最大值。对于这样的以为动态规划,可以简化为用一个变量f滚动完成更新。

int max_sum(int a[],int n)
{
    int f=a[0];
    int max_value=a[0];
    for(int i=1;i<n;i++)
    {
        if(f<0)
            f=a[i];
        else
            f=f+a[i];
        max_value=max(max_value,f);
    }
    return max_value;
}

问题二:不相交子数组和之差的最大值。

我们需要将数组分成不相交的两部分,分别求所有可能的两部分的子数组的和的最大值,以及最小值。比如将数组a[0~n]分成a[0~i]与a[i+1~n],我们用f1[i]表示第一部分a[0~i]子数组的最大连续子序列和。f2[i]表示第一部分a[0~i]子数组的最小连续子序列的和。g1[i+1]表示第二部分a[i+1~n]子数组的最大连续子序列和。g2[i+1]表示第二部分a[i+1~n]子数组的最小连续子序列的和。最后对于每一个i,我们求出最大的两部分之差,max(f1[i]-g2[i+1], g1[i+1]-f2[i]);其中f1[i],f2[i],g1[i],g2[i]都是在问题一的基础上求得的result;

int max_diff_sum(int a[],const int n)
{
    vector<int> f1(n);//f1[i]表示a[0~i]子数组中包含的所有连续子序列和的最大值
    vector<int> f2(n);
    vector<int> g1(n);
    vector<int> g2(n);
    f1[0]=a[0];
    f2[0]=a[0];
    int max_left_until=a[0];//表示以a[i]结尾的连续子序列的最大值
    int min_left_until=a[0];//表示以a[i]结尾的连续子序列的最小值
    for(int i=1;i<n;i++)
    {
        if(max_left_until>0)
            max_left_until+=a[i];
        else
            max_left_until=a[i];
        f1[i]=max(f1[i-1],max_left_until);

        if(min_left_until<0)
            min_left_until+=a[i];
        else
            min_left_until=a[i];
        f2[i]=min(f2[i-1],min_left_until);
    }

    g1[n-1]=a[n-1];
    g2[n-1]=a[n-1];
    int max_right_until=a[n-1];
    int min_right_until=a[n-1];
    for(int i=n-2;i>=0;i--)
    {
        if(max_right_until>0)
            max_right_until+=a[i];
        else
            max_right_until=a[i];
        g1[i]=max(g1[i+1],max_right_until);

        if(min_right_until<0)
            min_right_until+=a[i];
        else
            min_right_until=a[i];
        g2[i]=min(g2[i+1],min_right_until);
    }
    int result=INT_MIN;
    for(int i=0;i<n-1;i++)
    {
        result=max(result,max(f1[i]-g2[i+1],g1[i+1]-f2[i]));
    }
    return result;
}

问题三:最大连续乘积子串:

对于数组的最大连续乘积的子串,因为乘积可能有正有负,如果前面乘积为负的,刚好a[i]也是负数,就会负负得正。因此我们需要max_until来保存以a[i]结尾的子串的乘积的最大值,用min_until保存以a[i]结尾的子串的乘积的最小值。然后所有的max_until中的最大值为最后的结果。

double max_multi(double a[],int n)
{
    double max_until=a[0];
    double min_until=a[0];
    double result=a[0];
    for(int i=1;i<n;++i)
    {
        double temp1=max_until*a[i];
        double temp2=min_until*a[i];
        max_until=max(max(temp1,temp2),a[i]);
        min_until=min(min(temp1,temp2),a[i]);

        result=max(result,max_until);
    }
    return result;
}
时间: 2024-10-29 19:07:23

最大连续序列和,积以及不相交数组和之差最大的相关文章

输出有序数组的连续序列范围

Given a sorted integer array without duplicates, return the summary of its ranges. For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. 说明:0,1,2是连续的序列,则输出0->2 4,5又是另外一组连续的,则输出4->5 7单独是一个序列,输出7 注意数组没有元素(不一

算法题:找出一个数组中相加值最大的连续序列元素

package arithmetic; /** * @author SHI * 求一个数组中相加值最大的连续序列元素 */ public class MaxSequence { public static void main(String[] args) { int[] a=new int[]{-2,9,-3,4,-6,7,-6,4}; findBigSequence(a); } /** * 思想: (1)计算出该数组的所有元素和,假设该值为最大 * (2)从数组下标1到a.length-1依次

软件工程 最大连续序列和

今天软件工程课的时候,老师举个例子,最大的连续子序列的问题,自己在在脑中,想起来了在ACM中做过的题, 简要说一下思路:动态规划,找到状态转移方程是关键.定义两个数组a[],b[],一个存自己输入的数组,一个用来存连续和的值.状态转移方程:b[i]=max{b[i-1]+a[i],a[i]},找出最大的b[i]. 伪代码: for(循环) if(a[i]>0), b[i]=b[i-1]+a[i], else b[i]=a[i] 我选择用的是选择排序,比较一轮就知道最大是哪一个, max=b[0]

[LeetCode] Longest Consecutive Sequence 求最长连续序列

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example, Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run i

[Leetcode] Longest consecutive sequence 最长连续序列

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given[100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is[1, 2, 3, 4]. Return its length:4. Your algorithm should run in O(n

GEEK编程练习— —最长连续序列

题目 给定一个无序的整数数组,返回最长连续序列的长度.要求时间复杂度为O(n). 输入 [100, 4, 200, 1, 3, 2, 0, -1] 输出 6 分析 因为要求时间负责度为O(n),所以不能先排序再查找.所以想到查询最快的hash表,记录每个元素是否使用,对每个元素,往左右扩张,直到不连续为止. 代码 #include <iostream> #include <unordered_map> #include <algorithm> using namespa

128. 最长连续序列

给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4].它的长度为 4. class Solution(object): def longestConsecutive(self, num): """ :type nums: List[int] :rtype: int """ if num is

LeetCode 128. 最长连续序列(Longest Consecutive Sequence)

题目描述 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4].它的长度为 4. 解题思路 利用并查集的思想,构造一个map记录数组中以每个数所在的最长连续序列长度.每次遍历到一个数时,首先检查map中是否存在该数,若存在直接跳过,否则作如下更新操作: 找到左右相邻数字是否在map中,若存在则分别记录他们所在的最长连续序列长度,并更新当前的

【LeetCode】128. 最长连续序列

题目 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为O(n). 示例: 输入:[100, 4, 200, 1, 3, 2] 输出:4 解释:最长连续序列是[1, 2, 3, 4].它的长度为4 思路 思路一 先由小到大进行排序 考虑三种情况: 前后相差1,则是连续序列 前后相等,循环continue 最后一个元素,break 代码 def longestConsecutive(nums) -> int: ????if nums: ????????nums.sort()