数组坡的最大宽度问题| 豆包MarsCode AI刷题

29 阅读3分钟

问题描述

小U有一个整数数组 A,他想知道其中的坡的最大宽度。一个坡是指满足条件的元组 (i, j),其中 i < j 且 A[i] <= A[j]。这样的坡的宽度定义为 j - i。请你帮小U找出数组 A 中的坡的最大宽度。如果不存在符合条件的坡,则返回 0

输入输出

  • 输入

    • A:一个整数数组。
  • 输出

    • 一个整数,表示数组 A 中的坡的最大宽度。如果不存在符合条件的坡,则返回 0

测试样例

  • 样例1

    • 输入:A = [6, 0, 8, 2, 1, 5]
    • 输出:4
    • 解释:最大坡的宽度是 5 - 1 = 4,对应元组 (1, 5)
  • 样例2

    • 输入:A = [9, 7, 1, 0, 3, 9, 2, 9, 4, 1]
    • 输出:7
    • 解释:最大坡的宽度是 9 - 2 = 7,对应元组 (2, 9)
  • 样例3

    • 输入:A = [3, 3, 3, 3, 3]
    • 输出:4
    • 解释:最大坡的宽度是 4 - 0 = 4,对应元组 (0, 4)

思路解析

1. 暴力解法

最直接的方法是使用两层循环,遍历所有可能的 (i, j) 组合,检查是否满足 A[i] <= A[j],并计算坡的宽度。这种方法的时间复杂度为 O(n^2),在数组较大时效率较低。

func solution(A []int) int {
    max:=0
    for i:=0;i<len(A)-1&&len(A)-1-i>max;i++{
        for j:=len(A)-1;j>i;j--{
            if A[i]<=A[j]{
                if max<j-i{
                    max=j-i
                }
                break
            }
        }
    }
    return max
}

2. 优化解法

我们可以通过维护一个单调递减栈来优化这个过程。具体步骤如下:

  1. 从左到右遍历数组,维护一个单调递减栈,栈中存储的是数组的下标。
  2. 从右到左遍历数组,对于每个元素,检查栈顶元素是否满足 A[i] <= A[j],如果满足,则计算坡的宽度并更新最大宽度。
  3. 如果栈顶元素不满足条件,则弹出栈顶元素,继续检查下一个栈顶元素。

代码实现

package main

import (
	"fmt"
)

func solution(A []int) int {
    n := len(A)
    if n == 0 {
        return 0
    }
    
    // 单调递减栈
    stack := make([]int, 0)
    
    // 从左到右遍历数组,维护单调递减栈
    for i := 0; i < n; i++ {
        if len(stack) == 0 || A[i] < A[stack[len(stack)-1]] {
            stack = append(stack, i)
        }
    }
    
    maxWidth := 0
    
    // 从右到左遍历数组,计算最大坡的宽度
    for j := n - 1; j >= 0; j-- {
        for len(stack) > 0 && A[j] >= A[stack[len(stack)-1]] {
            width := j - stack[len(stack)-1]
            if width > maxWidth {
                maxWidth = width
            }
            stack = stack[:len(stack)-1]
        }
    }
    
    return maxWidth
}

代码解析

  1. 初始化

    • n:数组 A 的长度。
    • stack:单调递减栈,存储数组的下标。
  2. 维护单调递减栈

    • 从左到右遍历数组 A,如果当前元素 A[i] 小于等于栈顶元素对应的值,则将当前下标 i 压入栈中。
  3. 计算最大坡的宽度

    • 从右到左遍历数组 A,对于每个元素 A[j],检查栈顶元素是否满足 A[j] >= A[stack[len(stack)-1]]
    • 如果满足条件,计算坡的宽度 j - stack[len(stack)-1],并更新 maxWidth
    • 弹出栈顶元素,继续检查下一个栈顶元素。
  4. 返回结果

    • 返回 maxWidth,表示数组 A 中的坡的最大宽度。

总结

通过维护一个单调递减栈,我们可以将时间复杂度优化到 O(n),从而高效地计算出数组 A 中的坡的最大宽度。这种方法在处理大规模数据时也能保持较高的效率。