📌  相关文章
📜  国际空间研究组织 | ISRO CS 2017 |问题 24(1)

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

国际空间研究组织 | ISRO CS 2017 |问题 24

这是一道关于数据结构的编程题。题目描述如下:

一个长度为n的正整数序列,每个元素都是1到n之间的数。定义一个数为“左儿子”,当它在序列中是它左边第一个比它小的数;定义一个数为“右儿子”,当它在序列中是它右边第一个比它小的数。如果左儿子和右儿子都不存在,则称该数为“根”。

现在给定一个长度为n的正整数序列,请你编写程序,计算所有非根节点的左儿子和右儿子的和。

函数签名如下:

def  left_right_sum(n, a):
    pass
输入格式

第一行输入一个正整数 $n$,表示序列长度。

第二行输入 $n$ 个正整数,表示序列中的元素。

输出格式

输出所有非根节点的左儿子和右儿子的和。

输入样例
5
5 6 1 7 5
输出样例
12
代码实现

算法思路:

遍历整个序列即可,利用栈维护一个递减的序列,如果下一个数字比栈顶元素大,就说明栈顶元素的右子节点就是这个数,此时将栈顶元素出栈,直到遇到第一个比下一个数大的数为止;否则就将这个数入栈。栈中每个数在遍历完整个数列之前,如果它左边没有更小的数,那么它就是一个根节点;否则就可以计算出它的左儿子,也可以计算出它的右儿子。

def left_right_sum(n, a):
    stack = []
    res = 0
    for i in range(n):
        while len(stack) > 0 and a[stack[-1]] > a[i]:
            res += i + 1
            res += stack[-1]
            stack.pop()
        stack.append(i)
    while len(stack) > 0:
        res += stack[-1] + 1
        stack.pop()
    return res

调用函数:

n = 5
a = [5, 6, 1, 7, 5]
print(left_right_sum(n, a))  # 12

注意事项:

  1. 需要维护一个栈,存储递减的序列;
  2. 对于每个节点,可以通过栈找到它左边和右边的儿子;
  3. 遍历完整个序列后,仍需要检查栈中是否有元素,如果有,则它们都是根节点。