当前位置: 首页 > 知识库问答 >
问题:

最大和编码算法

穆德海
2023-03-14

我偶然发现了这个问题上的CodurityLessons,这里是描述:

给出了一个由N个整数组成的非空零索引数组A。

一个三元组(X,Y,Z),使得≤ 十、

双切片(X,Y,Z)的和是A[x1]A[x2]的总和。。。A[Y]− 1] A[Y 1]A[Y 2]。。。A[Z]− 1].

例如,数组A使得:

A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2

包含以下双切片示例:

双层(0,3,6),总和为2 6 4 5 = 17,

双层(0,3,7),和为2 6 4 5−1=16,

两片(3,4,5),和为0。

目标是找到任何双层片的最大和。

编写一个函数

整数解(向量)

给定一个由N个整数组成的非空零索引数组a,返回任意两个切片的最大和。

例如,假设:

A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2

该函数应该返回17,因为数组A的双层切片之和都不大于17。

假定:

N是范围[3...100,000]内的整数;数组A的每个元素都是范围[−10,000..10,000]内的整数。

复杂性:

预计最坏情况时间复杂度为O(N);预计最坏情况空间复杂度为O(N),超出输入存储(不计

可以修改输入数组的元素。

我已经读到过从索引i开始计数最大和以索引i结束的算法,但是我不知道为什么我的方法有时会给出不好的结果。这个想法是计算以索引i结束的最大和,忽略范围0的最小值... i。这是我的代码:

int solution(vector<int> &A) {
    int n = A.size();

    int end = 2;   

    int ret = 0;
    int sum = 0;

    int min = A[1];

    while (end < n-1)
    {
        if (A[end] < min)
        {
            sum = max(0, sum + min);
            ret = max(ret, sum);
            min = A[end];
            ++end;
            continue;
        }
        sum = max(0, sum + A[end]);
        ret = max(ret, sum);
        ++end;
    }

    return ret;
}

如果你能帮我指出漏洞,我会很高兴的!

共有3个答案

吉嘉珍
2023-03-14
def solution(A):
    n = len(A)
    K1 = [0] * n
    K2 = [0] * n
    for i in range(1,n-1,1):
        K1[i] = max(K1[i-1] + A[i], 0)

    for i in range(n-2,0,-1):
        K2[i] = max(K2[i+1]+A[i], 0)

    maximum = 0;
    for i in range(1,n-1,1):
        maximum = max(maximum, K1[i-1]+K2[i+1])

    return maximum

def main():
    A = [3,2,6,-1,4,5,-1,2]
    print(solution(A))

if __name__ == '__main__': main()
虞裕
2023-03-14

下面是我的代码:

int get_max_sum(const vector<int>& a) {
    int n = a.size();
    vector<int> best_pref(n);
    vector<int> best_suf(n);
    //Compute the best sum among all x values assuming that y = i.
    int min_pref = 0;
    int cur_pref = 0;
    for (int i = 1; i < n - 1; i++) {
        best_pref[i] = max(0, cur_pref - min_pref);
        cur_pref += a[i];
        min_pref = min(min_pref, cur_pref);
    }
    //Compute the best sum among all z values assuming that y = i.
    int min_suf = 0;
    int cur_suf = 0;
    for (int i = n - 2; i > 0; i--) {
        best_suf[i] = max(0, cur_suf - min_suf);
        cur_suf += a[i];
        min_suf = min(min_suf, cur_suf);
    }
    //Check all y values(y = i) and return the answer.
    int res = 0;
    for (int i = 1; i < n - 1; i++)
        res = max(res, best_pref[i] + best_suf[i]);
    return res;
 }

 int get_max_sum_dummy(const vector<int>& a) {
    //Try all possible values of x, y and z.
    int res = 0;
    int n = a.size();
    for (int x = 0; x < n; x++)
        for (int y = x + 1; y < n; y++)
            for (int z = y + 1; z < n; z++) {
                int cur = 0;
                for (int i = x + 1; i < z; i++)
                    if (i != y)
                        cur += a[i];
                res = max(res, cur);
            }
    return res;
 }

bool test() {
    //Generate a lot of small test cases and compare the output of 
    //a brute force and the actual solution.
    bool ok = true;
    for (int test = 0; test < 10000; test++) {
        int size = rand() % 20 + 3;
        vector<int> a(size);
        for (int i = 0; i < size; i++)
            a[i] = rand() % 20 - 10;
        if (get_max_sum(a) != get_max_sum_dummy(a))
            ok = false;
    }
    for (int test = 0; test < 10000; test++) {
        int size = rand() % 20 + 3;
        vector<int> a(size);
        for (int i = 0; i < size; i++)
            a[i] = rand() % 20;
        if (get_max_sum(a) != get_max_sum_dummy(a))
            ok = false;
    }
    return ok;
}

实际的解决方案是get_max_sum函数(另外两个是蛮力解决方案和一个tester函数,它生成一个随机数组,并比较蛮力和实际解决方案的输出,我仅将它们用于测试目的)。

我的解决方案背后的想法是计算子数组中的最大和,该子数组从i之前的某个地方开始,以i-1结束,然后为满足要求做同样的事情(best_pref[i]best_suf[i])。之后,我只需迭代所有I,并返回best_pref[I]best_suf[I]的最佳值。它工作正常,因为best_pref[y]为固定的y查找最佳的xbest_suf[y]为固定的y查找最佳的z,并检查y的所有可能值。

端木飞
2023-03-14

我的解决方案基于双向卡丹算法。更多细节在我的博客上。得分100/100。

public int solution(int[] A) {
  int N = A.length;
  int[] K1 = new int[N];
  int[] K2 = new int[N];

  for(int i = 1; i < N-1; i++){
    K1[i] = Math.max(K1[i-1] + A[i], 0);
  }
  for(int i = N-2; i > 0; i--){
    K2[i] = Math.max(K2[i+1]+A[i], 0);
  }

  int max = 0;

  for(int i = 1; i < N-1; i++){
    max = Math.max(max, K1[i-1]+K2[i+1]);
  }

  return max;
}
 类似资料:
  • 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。 实现方案如下: /** * @param {number[]}

  • 我在尝试解决求MaxDoubleSliceSum值的问题。简单地说,它是任何切片的最大和减去该切片中的一个元素(您必须删除一个元素,并且第一个和最后一个元素也被排除在外)。因此,从技术上讲,数组的第一个和最后一个元素不能包含在任何片和中。 以下是完整描述: 给出了一个非空的零索引数组由整数组成。三元组,使得 使得: 包含以下双切片示例: 双切片,总和 在给定由< code>N个整数组成的非空零索引

  • 问题内容: 我已经将我的Elasticsearch集群从1.1升级到1.2,并且在索引一个较大的字符串时出现错误。 索引的映射: 我搜索了文档,但没有找到与最大字段大小有关的任何内容。根据核心类型部分,我不明白为什么要为某个字段“校正分析仪” 。 问题答案: 因此,您遇到了一个术语的最大大小问题。当您将一个字段设置为not_analyzed时,会将其视为一个术语。基本Lucene索引中单个术语的最

  • 本文向大家介绍js计算最大公约数和最小公倍数代码实例,包括了js计算最大公约数和最小公倍数代码实例的使用技巧和注意事项,需要的朋友参考一下 一、计算最大公约数 1、小学时候一般采用质因数分解法,一般使用短除得到结果,下面用一种最初级的方法求最大公约数 2、使用欧里几德算法,辗转相除法。具体原理自行百度。下面给出两种代码算法 递归 迭代 二、最小公倍数,最小公倍数的算法,是两个数的乘积除以最大公倍数

  • 这个问题可能是封闭的,因为它听起来很模糊,但我真的问这个,因为我不知道或者我的数学背景不够。 我试图实现一个挑战,其中一部分挑战要求我计算矩阵的最小值和最大值。我对矩阵的实现及其操作没有任何问题,但是什么是矩阵的最小值和最大值?考虑到3x3矩阵是9个数中最小的数,最大的是最大的还是其他什么?

  • 我一直在纠结这件事。 最大子数组简单给定一个整数数组数,找到总和最大的相邻子数组(至少包含一个数字)并返回其总和。 子数组是数组的连续部分。 示例1: 输入:nums = [-2,1,-3,4,-1,2,1,-5,4]输出:6解释:[4,-1,2,1]的和最大= 6。示例2: 输入:nums=[1]输出:1示例3: 输入: 数字 = [5,4,-1,7,8] 输出: 23 我不明白迭代逻辑,视频中