📜  门| GATE-CS-2004 |问题7(1)

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

题目描述

给定一个含有N个整数的数组A,从A的一个位置开始计数,每隔一个元素向前跳跃1个位置,这样跳跃下去直到跳回起始位置。如果经过的元素之和是正数,则称这一圈“有盈利”,否则称这一圈“无盈利”。注意,整个过程中至少有一圈。

设计一个算法,找到“有盈利”圈中开始位置最靠前的位置。如果存在多个“有盈利”圈,则返回其中开始位置最靠前的一个。

示例

输入:
A = { 1 , -2 , 4 , -5 , 1 , -2 , 4 , -5 }
输出:
3
输入:
A = { 0 , 1 , 2 , 3 , 4 , 5 }
输出:
0

解题思路

这是一道比较经典的题目,可以用“部分和”思路来解决。 用sum数组来记录从起始点到每个位置下标的元素之和,计算出所有元素之和total,如果total<=0,那么无解。 否则,对于任意一个上标i,考虑从i到(i+len)%N(n为数组长度)中是否存在“有盈利”的圈。 如果sum[(i+len)%N]-sum[i]>0,那么i是一个可行答案。 注意:求模运算是为了避免越界,需要转为正数,即:(i+len)%N。

代码实现

def find_start_position(A):
    N = len(A)
    sumA = [0] * (N + 1)
    for i in range(1, N + 1):
        sumA[i] = sumA[i - 1] + A[i - 1]

    total = sum(A)
    if total <= 0:
        return -1

    for i in range(N):
        for j in range(1, N + 1):
            if sumA[(i + j) % N + 1] - sumA[i] > 0:
                return i

print(find_start_position([1, -2, 4, -5, 1, -2, 4, -5]))  # 3
print(find_start_position([0, 1, 2, 3, 4, 5]))  # 0