📌  相关文章
📜  计算左侧和右侧至少有一个较小元素的数组元素(1)

📅  最后修改于: 2023-12-03 15:41:38.828000             🧑  作者: Mango

计算左侧和右侧至少有一个较小元素的数组元素

在数组中,有些元素左侧或右侧存在至少一个比它小的元素,有些元素则不存在这样的元素。我们要找到这些存在左右至少一个较小元素的元素,并返回其下标。

解决方案

我们可以使用单调栈来解决这个问题。我们遍历数组,维护一个单调递减的栈。对于当前元素,我们判断它是否比栈顶元素小。如果是,我们弹出栈顶元素,并将弹出的元素左侧第一个比它小的元素下标设为其下标,将当前元素压入栈中。否则,我们将当前元素压入栈中,并将其左侧第一个比它小的元素下标设为弹出的栈顶元素的下标。

这样,在栈中的元素都是存在左右至少一个较小元素的元素。我们只需要将栈中的元素依次取出,并计算它右侧第一个较小元素的下标即可。

代码实现

以下是Python实现的代码片段:

def find_smaller_elements(arr):
    n = len(arr)
    stack = []
    left_smaller = [-1] * n
    right_smaller = [-1] * n

    # 计算左侧第一个较小元素的下标
    for i in range(n):
        while stack and arr[i] < arr[stack[-1]]:
            idx = stack.pop()
            left_smaller[idx] = i - 1
        stack.append(i)

    # 清空栈,计算右侧第一个较小元素的下标
    stack.clear()
    for i in range(n - 1, -1, -1):
        while stack and arr[i] < arr[stack[-1]]:
            idx = stack.pop()
            right_smaller[idx] = i + 1
        stack.append(i)

    # 计算存在左右至少一个较小元素的元素
    res = []
    for i in range(n):
        if left_smaller[i] == -1 or right_smaller[i] == -1:
            res.append(i)

    return res

在以上代码中,我们使用了两个辅助数组left_smallerright_smaller来记录每个元素的左侧和右侧第一个较小元素的下标。在计算左侧第一个较小元素的下标时,我们在栈中存储的是原数组的下标,而不是元素本身。这是因为我们需要通过下标来计算每个元素的右侧第一个较小元素的下标。

最后,我们依次遍历每个元素,判断它是否存在左右至少一个较小元素的元素即可。