当前位置: 首页 > 知识库问答 >
问题:

数组中的索引,使其前缀和等于后缀和-最佳解决方案

澹台举
2023-03-14

问题

给出了一个由N个整数组成的零索引数组A。该数组的平衡索引是任何整数P,使得<代码>0≤P

A[0] + A[1] + ... + A[P−1] = A[P+1] + ... + A[N−2] + A[N−1].

假设零元素之和等于0。如果P=0P=N,则可能发生这种情况−1

N的范围:[0…100000]

元素范围:[−2,147,483,648 ... 2,147,483,647]

复杂性:最坏情况时间O(N)

我的5分钟解决方案

这是一个直观的解决方案,通过计算公式性能是O(N^2),因为它为每个迭代求和所有数组,并且它不适用于大型条目。

def solution(A):
    result = []
    for i in xrange(len(A)):
        if sum(A[:i]) == sum(A[i+1:]):
            result.append(i)
    if result == []:
        return -1
    return result

最佳解决方案

这个解决方案是O(N)有人能解释一下这个解决方案背后的逻辑吗?

def equi(A):
    result = []
    x=1
    i=1
    r=sum(A)
    for e in A:
        i-=1
        r-=2*e
        if -e==r:
            result.append(-i)
    return result

共有3个答案

诸葛砚文
2023-03-14

另一种方法如下:

>

sumA, prevSum, n = sum(A), 0, len(A)

接下来让我们考虑每一次迭代会发生什么。我们声明一个变量,例如rem,它是(sumA-prevSum-a[i])的值。本质上,在每次迭代中,我们都希望从数组的和中删除前一个和(prevSumleftSum),并删除当前值。

然后我们检查是否rem==preSum。如果这是true,我们返回索引,如果是false,我们重复这个循环,直到数组中的所有元素都被检查到这一点,我们返回一个Falsy值。

这里有相关代码

姜松
2023-03-14

O(n)解决方案有点太聪明了,有点模糊,但它工作得很好。我已经用有意义的变量名重写了它,并将一些东西移动了一下,以使它的工作原理更加清晰。

def equilibriums(A):               # line 1
    result = []                    # line 2
    difference = sum(A)            # line 3
    
    for p in range(len(A)):        # line 4
        
        difference -= 2*A[p]       # line 5
        
        if difference == -A[p]:    # line 6
            result.append(p)       # line 7
        
    return result                  # line 8

现在解释一下。让

left  = 0,
right = A[0] + A[1] + ... + A[N-2] + A[N-1] = sum(A), and
difference = right - left = sum(A) - 0 = sum(A)    # <-- explains line 3

当将A[0]从right中删除并添加到中时,差异将按2*A[0]向下移动。如果将A[1]从right移动到差异将按2*A[1]向下移动。每当元素A[p]被移动时,差异将按2*A[p]向下移动。这解释了第4行和第5行。

现在,在平衡指数P,我们有:

A[0] + A[1] + ... + A[P−1] = A[P+1] + ... + A[N−2] + A[N−1]                # definition
                           = A[P+1] + ... + A[N−2] + A[N−1] + A[P] - A[P]  # add A[P]-A[P]
                           = A[P] + A[P+1] + ... + A[N−2] + A[N−1] - A[P]  # rearrange
\---- but this = left ---/   \--------- and this = right --------/

或者,

left = right - A[P]

difference = right - left                 # definition
           = right - (right - A[P])       # substitute
           = A[P]                         # simplify

如果我们将A[P]right移动到差异将下降2*A[P],现在

difference = A[P] - 2*A[P] = -A[P]

也就是说,当平衡点从right移动到now时,差异A[P]移动到-A[P]。因此,如果差异==-A[P],那么P就是一个均衡索引。这解释了第6行中的测试。

注意,并不是算法真正需要的。它们只是用来解释的。

equilibriums([1,2,3,0,1,0,0,0,0,1,6])  ==> returns [5, 6, 7, 8]
商高谊
2023-03-14

我相信你发布的解决方案根本不起作用,而且很难理解。以下是我的看法:

def equi(v):
    left_sum = 0       # sum(v[:p]) at all times.
    right_sum = sum(v) # sum(v[p+1:]) at all times.

    for i in xrange(len(v)):
        right_sum -= v[i]
        if left_sum == right_sum:
            return i   # your p.
        left_sum += v[i]
    return -1 # Because, there may not be an equilibrium index at all.

基本上,不用在循环的每次迭代中重新计算sum(左边)和sum(右边),你可以用简单的数学计算出来。

用大小为n的数组表示:

pos1 = i
left_sum1 = v[0] + v[1] + ... + v[i-1]
right_sum1 = v[i+1] + v[i+2] + ... + v[n-1]

现在让我们前进一步,检查我们应该拥有什么:

pos2 = i+1
left_sum2 = v[0] + v[1] + ... + v[i]
right_sum2 = v[i+2] + v[i+2] + ... + v[n-1]

现在,发生了什么变化?

left_sum2 - left_sum1 = v[i]
right_sum2 - right_sum1 = -v[i+1]

这可能会让人困惑,但应该清楚地看到,通过对之前的值进行加减,可以得到任意点的左右两边之和。

 类似资料:
  • 以下是我的任务描述: 给出了一个由N个整数组成的零索引数组。 这个数组的平衡指数是任意整数P,0≤ P 假设零元素之和等于0。如果P=0或P=N,则可能发生这种情况−1、例如,考虑下面的数组A,由n=8个元素组成: 没有指数大于7的元素。P=8不是平衡指数,因为它不满足0≤P的条件 编写一个函数:int solution(NSMutableArray*a);给定一个由N个整数组成的零索引数组a,它

  • 当你编写一个算术表达式如 B*C 时,表达式的形式使你能够正确理解它。在这种情况下,你知道 B 乘以 C, 因为乘法运算符 * 出现在表达式中。这种类型的符号称为中缀,因为运算符在它处理的两个操作数之间。看另外一个中缀示例,A+B*C,运算符 + 和 * 仍然出现在操作数之间。这里面有个问题是,他们分别作用于哪个运算数上,+ 作用于 A 和 B , 还是 * 作用于 B 和 C?表达式似乎有点模糊

  • 本文向大家介绍数据结构中的前缀和后缀表达式,包括了数据结构中的前缀和后缀表达式的使用技巧和注意事项,需要的朋友参考一下 编写算术表达式的方法称为符号。算术表达式可以用三种不同但等效的符号表示,即,无需更改表达式的本质或输出。这些符号是– 中缀 字首 后缀 缀符号是正常的符号,我们在编写不同的数学表达式时会使用它们。前缀和后缀表示法有很大不同。 前缀符号 在这种表示法中,运算符以操作数为前缀,即运算

  • 我目前正在做codingbat问题的乐趣,我刚刚做了这个问题。 “给定一个字符串,考虑由字符串的前N个字符组成的前缀字符串。该前缀字符串是否出现在字符串的其他地方?假设字符串不是空的,并且N在1..str.length()的范围内。前缀再次(”abxyabc“,1)→真前缀再次(”abxyabc“,2)→真前缀再次(”abxyabc“,3)→假”http://codingbat.com/prob/

  • 学习lvalue和rvalue。定义是“address of”是左值,否则是rvalue。 我检查了运算符的优先级,前缀和后缀增量都比“address of”运算符有更高的优先级。 对于下面的两个示例,谁能解释一下为什么第一个“&++value1”是lvalue,而第二个“&value1++”是RValue。 我对这两种情况的错误理解是:pValue1指向value1变量。无论在建立地址相关性之前

  • 因此,我试图在SML中创建一个解析器程序,提示用户输入表达式。然后,它会告知输入的表达式是后缀、前缀还是中缀,然后显示结果。下面是我希望它做的一个示例: 我在创建函数时遇到了麻烦,这样它就会向屏幕输出结果,我不确定我是否正确地执行了该方法。在我首先计算出转换之前,我甚至不会专注于输出树。 我觉得我应该在第二个if语句中放一个递归方法(检查与运算符是否相等),但由于Alice SML语法的限制,我不