【问题标题】:Find the maximum possible value [closed]找到最大可能值[关闭]
【发布时间】:2020-01-20 04:52:38
【问题描述】:

给定数组的第一个和最后一个整数 ab,以及数组的大小 -- n,其中n-1 >= |a-b|。 数组中相邻整数的差不超过 1。 在满足上述条件的所有可能的数组中,找出第一个和最后一个整数之间的数的最大值(不包括给定的第一个和最后一个整数)。

Example 1:
a = 3, b = 3, n = 5
Some possible arrays:
[3, 4, 5, 4, 3]
[3, 2, 1, 2, 3]
[3, 4, 4, 4, 3]
...
The maximum value is 5.

Example 2:
a = 5, b = 6, n = 5
Some possible arrays:
[5, 5, 5, 5, 6]
[5, 5, 6, 7, 6]
[5, 6, 7, 6, 6]
[5, 6, 7, 7, 6]
...
The maximum value is 7.

Example 3:
a = 8, b = 5, n = 4
[8, 7, 6, 5] -- the only array that can be formed
The maximum value is 7 (8 does not count since it is the first number that has been given).

Example 4:
a = 5, b = 8, n = 4
[5, 6, 7, 8] -- the only array that can be formed
The maximum value is 7 (8 does not count).

如何解决这个问题?我知道当 a == b 时该怎么做,但不确定其他情况。

【问题讨论】:

  • 不幸的是,您似乎只是在要求其他人为您编写代码,因此您的问题可能会被关闭。为避免这种情况发生,您能否更新您的问题以显示您迄今为止编写的代码?
  • 这种情况下的二进制搜索似乎与我相关,时间复杂度为 O(log(n))。

标签: java arrays algorithm max


【解决方案1】:

说明

由于相邻整数的差异不能超过 1,因此您首先需要递增结束值 ab 中的较低值,直到它们相等。

a = 3, b = 3, n = 5
[3, _, _, _, 3]

a = 3, b = 5, n = 5
[3, _, _, _, 5]
[3, 4, _, _, 5]
[3, 4, 5, _, 5]

a = 5, b = 3, n = 5
[5, _, _, _, 3]
[5, _, _, 4, 3]
[5, _, 5, 4, 3]

因此,您将为 2 个结束值使用 2 个空格,再加上一个 |a-b| 空格以“均衡”较大结束值处的值:

remain = n - 2 - Math.abs(a - b)

剩下的空格,需要从两边递增,所以只能递增remain / 2次,四舍五入

incr = (remain + 1) / 2

这意味着可能的最大值是incr 大于最大最终值的数字:

max = Math.max(a, b) + incr;

全部合并:

max = Math.max(a, b) + (n - Math.abs(a - b) - 1) / 2

但是,有两种特殊情况:

  • 如果 n = 2,则结束值之间将没有值,因此n <= 2 无效,因为没有答案。

  • 如果有足够的空间从较低的值到达较高的值,例如a = 3, b = 7, n = 5: [3, 4, 5, 6, 7],这意味着上面的第一步将失败,因为我们无法“均衡”较大最终值的值。在这种特殊情况下,最高非终值比最高终值低 1:

max = Math.max(a, b) - 1

解决方案

所以,总而言之,计算最高非终值的代码是:

static int max(int a, int b, int n) {
    int extra = (n - Math.abs(a - b) - 1);
    if (n <= 2 || extra < 0)
        throw new IllegalArgumentException();
    return (extra == 0 ? Math.max(a, b) - 1 : Math.max(a, b) + extra / 2);
}

性能是O(1),因为结果是一个简单的计算,不需要实际构建数组来找到结果。


测试

public static void main(String[] args) {
    test(3, 3, 5); // max from question: 5
    test(5, 6, 5); // max from question: 7
    test(8, 5, 4); // max from question: 7
    test(5, 8, 4); // max from question: 7
    test(3, 5, 5);
    test(5, 3, 5);
    test(3, 7, 5);
    test(3, 7, 6);
    test(3, 7, 7);
    test(3, 7, 8);
    test(3, 7, 9);
}
static void test(int a, int b, int n) {
    System.out.printf("a = %d, b = %d, n = %d: The maximum value is %d. %s%n",
                      a, b, n, max(a, b, n), Arrays.toString(fill(a, b, n)));
}
static int[] fill(int a, int b, int n) {
    int[] v = new int[n];
    int i = 0, j = n - 1;
    v[i] = a;   v[j] = b;
    for (; v[i] < v[j]; i++)
        v[i + 1] = v[i] + 1;
    for (; v[i] > v[j]; j--)
        v[j - 1] = v[j] + 1;
    for (; i + 1 < j; i++, j--)
        v[i + 1] = v[j - 1] = v[i] + 1;
    return v;
}

输出

a = 3, b = 3, n = 5: The maximum value is 5. [3, 4, 5, 4, 3]
a = 5, b = 6, n = 5: The maximum value is 7. [5, 6, 7, 7, 6]
a = 8, b = 5, n = 4: The maximum value is 7. [8, 7, 6, 5]
a = 5, b = 8, n = 4: The maximum value is 7. [5, 6, 7, 8]
a = 3, b = 5, n = 5: The maximum value is 6. [3, 4, 5, 6, 5]
a = 5, b = 3, n = 5: The maximum value is 6. [5, 6, 5, 4, 3]
a = 3, b = 7, n = 5: The maximum value is 6. [3, 4, 5, 6, 7]
a = 3, b = 7, n = 6: The maximum value is 7. [3, 4, 5, 6, 7, 7]
a = 3, b = 7, n = 7: The maximum value is 8. [3, 4, 5, 6, 7, 8, 7]
a = 3, b = 7, n = 8: The maximum value is 8. [3, 4, 5, 6, 7, 8, 8, 7]
a = 3, b = 7, n = 9: The maximum value is 9. [3, 4, 5, 6, 7, 8, 9, 8, 7]

【讨论】:

    【解决方案2】:

    看起来像家庭作业,所以只是一个想法:

    尝试在数组中绘制值图。请注意,具有所描述属性的数组可能看起来像锯齿,但当绘图包含唯一的峰值时,最大的内部值是可能的。

    如果端点差异太大(您的最后一个示例),则最大值位于较大的末端邻居处,否则尝试使用最大峰值构建图 - 请注意可能的斜率仅为 -1,+1(也许奇数 n 值的单个普通步骤)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 2012-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多