【问题标题】:How to find maximum sum of smallest and second smallest elements chosen from all possible subarrays如何找到从所有可能的子数组中选择的最小元素和次小元素的最大和
【发布时间】:2021-08-29 01:18:11
【问题描述】:

给定一个数组,从所有可能的子数组中找出最小元素和次小元素的最大和。更正式地说,如果我们写出所有 (nC2) 个大小 >=2 数组的子数组,并找到最小和第二小的和,那么我们的答案将是它们之间的最大和。

Examples: Input : arr[] = [4, 3, 1, 5, 6] Output : 11`

Subarrays with smallest and second smallest are,
[4, 3]        smallest = 3    second smallest = 4
[4, 3, 1]    smallest = 1    second smallest = 3
[4, 3, 1, 5]    smallest = 1    second smallest = 3
[4, 3, 1, 5, 6]    smallest = 1    second smallest = 3
[3, 1]         smallest = 1    second smallest = 3
[3, 1, 5]     smallest = 1    second smallest = 3
[3, 1, 5, 6]    smallest = 1    second smallest = 3
[1, 5]        smallest = 1    second smallest = 5
[1, 5, 6]    smallest = 1    second smallest = 5
[5, 6]         smallest = 5    second smallest = 6
Maximum sum among all above choices is, 5 + 6 = 11

这个问题是关于GFG的,但我不明白它的解释。

请任何人给出 O(n) 时间复杂度的解决方案。

【问题讨论】:

  • 您所指的GeeksforGeeks article包含6种语言的解释和实现。你的问题到底是什么?如果你想让我们解释一下为什么 GFG 上给出的解决方案是正确的:你了解它的什么,你在哪里理解它有困难?
  • @He3lixxx 实际上我不明白这个问题是如何减少到在数组中找到两个连续元素的最大总和?
  • 我们需要检查所有连续的对,找到最大的对,就是这样!
  • @potter1024 这是我的问题,这个问题是如何减少到找到数组中两个连续元素的最大总和?
  • 假设我们取一个超过 2 个数字的子数组,那么我们必须选择最小的和次小的。因此,其他数字是否很大并不重要。重要的是最小的 2 个数字。

标签: algorithm data-structures


【解决方案1】:

首先你没有理解这个问题!如果您仔细考虑所有子数组,最后您可以看到所有子数组都是相关的;换句话说,我们正在考虑将previous sub-array 的结果转换为current sub-array

Subarrays with smallest and second smallest are,
[4, 3]        smallest = 3    second smallest = 4
[4, 3, 1]    smallest = 1    second smallest = 3
[4, 3, 1, 5]    smallest = 1    second smallest = 3
[4, 3, 1, 5, 6]    smallest = 1    second smallest = 3
[3, 1]         smallest = 1    second smallest = 3
[3, 1, 5]     smallest = 1    second smallest = 3
[3, 1, 5, 6]    smallest = 1    second smallest = 3
[1, 5]        smallest = 1    second smallest = 5
[1, 5, 6]    smallest = 1    second smallest = 5
[5, 6]         smallest = 5    second smallest = 6
Maximum sum among all above choices is, 5 + 6 = 11

从每个子数组:

1. we are taking the current largest value and if it is greater than previous largest we are replacing, and previous largest eventually becomes second most largest.
2. we are repeating this steps for every possible subarray (increasing in terms of index).
3. and at the end you can see, we are taking first-most and second-most value from the array.

因此检查数组中的每一对值可以降低O(N) 中的整体复杂性

int res = arr[0] + arr[1];  //O(1)+O(1)
for (int i=1; i<N-1; i++)   // O(N-2) -> O(N)
   res = max(res, arr[i] + arr[i+1]); //O(1)+O(1)+O(1)

总体复杂度:O(N)。

【讨论】:

    【解决方案2】:

    问题是: 如果我们只查看所有长度为 2 的子数组,为什么总能保证找到最大和?

    要回答这个问题,假设我们有一些数组 A。显然,在该数组内部,必须至少有一个子数组 S,其中最小和第二小的元素,我们称它们为 X 和 Y,总和为我们的结果。

    如果这两个元素已经彼此相邻,这意味着有一个长度为 2 的 A 子数组将包含 X 和 Y,因此,如果我们只查看所有长度为 2 的子数组,我们将求 X 和 Y 并输出 X+Y。

    但是,问题是:有没有办法让我们的两个元素 X 和 Y 不成为 S 中的“邻居”?好吧,如果是这样的话,显然需要其他数字,我们称它们为 Z0,Z1,...,在它们之间。

    显然,对于所有这些值,它必须持有 Zi >= X 和 Zi >= Y,因为在 S 中,X 和 Y 是最小和第二小的元素,所以不能有其他数字小于X 或 Y。

    如果任何一个 Zi 比 X 或 Y 大,这将意味着 A 的一个子数组只包括这个更大的 Zi 加上它的邻居。在这个子数组中,Zi 和它的邻居将是最小和第二小的元素,它们的总和将比 X+Y 更大,所以我们的子数组 S 不会是给我们解决方案的子数组。这与我们对 S 的定义相矛盾,所以这不可能发生。

    所以,所有的 Zi 都不能小于 X 或 Y,它们也不能大于 X 或 Y。这只留下了一种可能性:对于 X == Y,它们都可以相等。但是,在这种情况下,我们显然还有一个长度为 2 的子数组,它总和为我们的正确结果。

    因此,在所有情况下,我们都可以证明必须有一个长度为 2 的子数组,其中两个元素相加为我们的结果,这就是算法正确的原因。

    【讨论】:

    • tnx 的解释。
    猜你喜欢
    • 2013-12-15
    • 2020-09-22
    • 1970-01-01
    • 2017-01-17
    • 2019-08-31
    • 1970-01-01
    • 2018-10-17
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多