这是在OA中提出的.给定一个大小为n的正整数array.

对于数组中的每个项目(索引范围从0n - 1),找到包含当前项目的最大子数组的大小,使得当前项目等于该子数组中的最大元素,并将该大小添加到结果(从0开始).

Example:

arr = [3,5,6]
Result = 6

Explanation:

i=0 => [3] = max subarray with 3 as maximum, size of sub-array is 1

i=1 => [3,5] = max subarray with 5 as maximum, size of sub-array is 2

i=2 => [3,5,6] = max subarray with 6 as maximum, size of sub-array is 3

Sum  = 1 + 2 + 3 = 6

Example:

arr = [ 1,2,1]
Result = 5

Explanation:

i = 0 => [1] max subarray, size = 1
i = 1 => [1, 2, 1] max subarray with 2 as maximum, size = 3
i = 2 => [1], max subarray with 1 as maximum, size = 1

Result = 1 + 3 + 1 = 5

Example:

arr = [1,1,1,1]
Result = 16

Explanation:

i = 0 => [1, 1, 1, 1] max subarray with 1 as maximum, size = 4
Same for i=1, 2, 3 => max subarray for each case is still [1,1,1,1] with size 4
Result = 4 + 4 + 4 + 4 = 16

下面是我的代码:

public class Main {

  public static int solve(int[] arr) {
    int n = arr.length;
    int result = 0;
    int currentMax = Integer.MIN_VALUE;

    int size = 0;
    for (int i = 0; i < n; i++) {
      currentMax = Math.max(currentMax, arr[i]);
          
      if (arr[i] == currentMax) {
          size++;
          int backUp = size;
          for(int j=i+1; j<n; j++) {
              if(arr[j] <= currentMax) {
                  size++;
              } else {
                  break;
              }
          }
        result += size;
        size = backUp;
      } else {
          size = 1;
          currentMax = arr[i];
          result++;
      }
    }

    return result;
  }

  public static void main(String[] args) {
    System.out.println(solve(new int[]{3,5,6}));//6
    System.out.println(solve(new int[]{1,2,1}));//5
    System.out.println(solve(new int[]{1,1,1,1}));//16
  }
}

我的代码只适用于示例测试用例,而对于隐藏的其他用例则失败了,所以我无法看到它们.什么是正确的方法来解决这个问题,测试用例失败说错误的输出,没有超时错误.

推荐答案

这个问题本质上只需要为数组的每个元素找到两边最接近的较大元素.这可以在O(n)中实现.

public static long solve(int[] arr) {
    var dq = new ArrayDeque<Integer>(arr.length);
    int[] prevLarger = new int[arr.length], nextLarger = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        while (!dq.isEmpty() && arr[dq.peek()] <= arr[i]) dq.pop();
        prevLarger[i] = dq.isEmpty() ? -1 : dq.peek();
        dq.push(i);
    }
    dq.clear();
    for (int i = arr.length - 1; i >= 0; i--) {
        while (!dq.isEmpty() && arr[dq.peek()] <= arr[i]) dq.pop();
        nextLarger[i] = dq.isEmpty() ? arr.length : dq.peek();
        dq.push(i);
    }
    long ans = 0;
    for (int i = 0; i < arr.length; i++) ans += nextLarger[i] - prevLarger[i] - 1;
    return ans;
}

Java相关问答推荐

如何在PFA中使用不确定的进度指标制作可暂停的任务?

在URL类图中表示Java swing类

具有默认分支的JUnit代码覆盖率切换声明

BiPredicate和如何使用它

Java在模块化jar文件中找不到类,但是javap可以

Select 按位运算序列

Java模式匹配记录

为什么我的ArrayList索引的索引总是返回-1?

为什么JAVA&S清洁器使用链表而不是并发HashSet?

Chunk(Int)已弃用并标记为要删除

未找到适用于响应类型[类java.io.InputStream]和内容类型[Text/CSV]的HttpMessageConverter

SonarLint:只能有条件地调用方法(S)

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

在settings.gradle.kts和Build.gradle.kts中使用公共变量

如何使这两种方法合二为一?

如果第一位数字和最后一位数字相差超过一位,您将如何获得随机数?

在实例化中指定泛型类型与不指定泛型类型之间的区别

接受类及其接口的Java类型(矛盾)

在Spring Boot中使用咖啡因进行缓存-根据输出控制缓存

始终使用Spring Boot连接mongodb上的测试数据库