📌  相关文章
📜  从左侧只能看到 K 条的方式数(1)

📅  最后修改于: 2023-12-03 14:49:24.187000             🧑  作者: Mango

从左侧只能看到 K 条的方式数

在这个主题下,我们将探讨如何编写程序来计算从左侧只能看到 $K$ 条的方式数。在这个问题中,有 $N$ 条线段垂直于 x 轴,每条线段有一个高度 $H_i$,我们需要求出从左侧只能看到 $K$ 条线段的方式数。

思路

我们可以使用单调栈来解决这个问题。从左到右遍历每条线段,对于每条线段 $i$,我们需要弹出所有高度小于等于 $H_i$ 的线段。为了计算从左侧能看到 $K$ 条线段的方式数,我们需要知道对于任意一个线段 $j\ (j<i)$,在它左侧有多少个高度大于等于 $H_j$ 的线段。这就是这道题的关键点。

我们可以维护一个单调递减的栈,栈中存储的是线段的下标。我们遍历到线段 $i$ 时,先弹出栈顶的线段,直到栈顶的线段高度大于 $H_i$ 或者栈为空为止。在这个过程中,我们可以计算出从 $j$ 往左侧能看到的线段个数。

设 $k$ 是第一个满足 $H_k > H_i$ 的线段,则从 $j$ 往左侧能看到的线段个数为 $i-k$。这是因为线段 $k+1$ 至线段 $i-1$ 的高度都小于等于 $H_i$,而线段 $k$ 的高度大于 $H_i$。因此,从 $j$ 往左侧能看到的线段个数就是 $i-k$。

具体的实现细节可以看下面的代码。

代码
def solution(heights, k):
    n = len(heights)
    stack = []
    ans = 0
    for i in range(n):
        while stack and heights[stack[-1]] <= heights[i]:
            stack.pop()
        if len(stack) < k:
            ans += 1
        if len(stack) == k:
            ans += stack[-1] - stack[-2]
        stack.append(i)
    return ans

具体的代码实现如上,其中 heights 是一个长度为 $N$ 的数组,存储每条线段的高度;k 是我们需要计算的从左侧只能看到的线段个数。函数的返回值即是从左侧只能看到 $K$ 条线段的方式数。

小结

本文介绍了如何用单调栈来计算从左侧只能看到 $K$ 条线段的方式数。这个问题中的关键点是计算从 $j$ 往左侧能看到的线段个数,可以通过维护一个单调递减的栈来实现。希望本文能对大家有所帮助。