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

在数组中查找平衡点

拓拔弘厚
2023-03-14

这个问题来自一个很棒的YouTube频道,给出了可以在采访中提出的问题。

它基本上与寻找数组中的平衡点有关。这里有一个例子来最好地解释它;{1,2,9,4,-1}.因为sum(1 ^ 2)= sum(4(-1))使9成为平衡点。在没有检查答案的情况下,我决定先实现这个算法,想问问是否有更有效的方法;

    < li >对数组O(n)中的所有元素求和 得到总数的一半O(1) < li >从左侧开始扫描数组,当< b>sumleft大于一般总和的一半时停止。O(n) < li >对右侧进行同样的操作,以获得< b>sum right。O(n)。 < li >如果sumleft等于sumright,则返回arr[size/2],否则返回-1

我之所以问这个问题,是因为这个解决方案毫不费力地出现在我的脑海中,提供了O(n)的运行时间。如果这种解决方案是真的,是否可以开发,或者如果不是真的,是否有任何替代方法?

共有3个答案

华泽语
2023-03-14

我实际上有两个起点,一个在最左边的点(leftLoc),一个在右边的点(rightLoc)。保持左和右数字相加。

leftLoc  = 0;
rightLoc = (n - 1);
sumRight = array[rightLoc];
sumLeft  = array[leftLoc];

while(leftLoc < rightLoc){
    if(sumRight > sumLeft){
        leftLoc++;
        sumLeft += array[leftLoc];
    }else{
        rightLoc--;
        sumRight += array[rightLoc];
    } 
}

if( (sumRight + array[rightLoc - 1]) == sumLeft ){
    return rightLoc--;
}else if( (sumLeft + array[leftLoc + 1]) == sumRight){
    return leftLoc++;
}else{
    // return floating point number location in the middle of the 2 locations
}

同时跟踪已移动 O(n) 的总位置数

您可能会发现您的平衡点是最后点中间的浮点数(一旦它们位于彼此相邻的整数位置)。

这甚至适用于负数的例子。也许我遗漏了一些细节,但是这个主题的一些变化应该会产生O(n)运行时算法。

子车征
2023-03-14
匿名用户

基本上先把所有的数字加起来。这将是一个O(n)操作。然后从数组的开头开始,一次从数组中减去一个元素,直到<code>上限==<code>下限。因此,总阶数为O(n)。

int BalancePoint(int a[], int begin, int end) // find index of an array (balance point) such that sum of all elements before the index = sum of all elements after it; else return -1
{
    if(!a) return -1;
    else if(begin == end) return begin;

        long long upper = 0;
        long long lower = 0;

    for(int i = begin; i <= end; ++i)
    {
        upper += *(a+i);
    }

    for(int j = begin; j <= end; ++j)
    {
        upper -= *(a+j);
        if(upper == lower) return j;
        lower += *(a+j);
    }
    return -1;
}

使用STL

int BalancePointSTL( const vector<int> &A ) // find index of an array (balance point) such that sum of all elements before the index = sum of all elements after it; else return -1
{
    if(A.empty()) return -1;

        long long upper = 0;
        long long lower = 0;

    for(unsigned int i = 0; i <= A.size(); ++i)
    {
        upper += A[i];
    }

    for(unsigned int j = 0; j < A.size(); ++j)
    {
        upper -= A[j];
        if(upper == lower) return j;
        lower += A[j];
    }
    return -1;
    }

以下将具有更好的最坏情况性能,但会有更多的if-fe比较

int BalancePoint2(int a[], int begin, int end) // Better worst case senario by factor of 2
{
    if(!a) return -1;
    else if(begin == end) return begin;

        long long upper = 0;
        long long lower = 0;

        int mid = (end-begin)/2;

        for(int i = begin; i < mid; ++i)
        {
            lower += *(a+i);
        }
        for(int i = mid+1; i <= end; ++i)
        {
            upper += *(a+i);
        } 

        if(upper == lower) return mid;
        else if(lower < upper)
        {
            lower += *(a+mid);
            for(int i= mid + 1 ; i <= end ; ++i)
            {
                upper -= *(a + i);
                if(upper == lower) return i;
                lower += *(a + i);
            }
        }
        else {
            upper += *(a + mid);
            for(int i = mid - 1; i >=begin; --i)
            {
                lower -= *(a + i);
                if(upper == lower) return i;
                upper += *(a + i);
            }
        }
        return -1;
}

寿亦
2023-03-14

你的算法不好(反例:1-1011-1111),好的解决方案是计算数组的部分和(这样你就可以为数组的每个单元格计算O(1)中的sumleetSumlright),然后(或者如果你已经知道全局和),在数组中搜索一个单元格,使得SUmleet=sumlright>/code>,这是O(n)。

数组A的部分和是

[A[0], A[0]+A[1], A[0]+A[1]+A[2], …, A[0]+A[1]+A[2]+…+A[n-1]]

示例:

A=[5,2,3,1,4,6]
partial sum = [5,7,10,11,15,21]

使用这个数组,您可以计算sum right[i]=partial_sum[i-1]sum right[i]=partial_sum[n-1]-partial_sum[i]

改进:

如果存储所有的partial_sum数组,则首先计算全局和,然后只计算当前索引的部分和,这样可以只使用O(1)个额外空间,而不是O(n)个额外空间。

 类似资料:
  • 我有一个<code>BinarySearchTree</code>,里面有Instance bankaccount的对象,这是我创建的一个类,所以基本上它只是一个二进制搜索树,我编写了一个方法,它将获取树并对其进行平衡,因为某些原因,它在平衡之前准确地打印出树: 现在,首先我有方法,它接受一个列表和一个并通过按顺序检查树数据来创建树数据的,因此它是一个排序数组。然后使用另一种方法以平衡的方式创建树

  • 我正在尝试使用用户输入将数字放入一个数组,然后找到这些数字的平均值,也找到哪些数字大于平均值。这些数字进入一个数组,但当我试图求平均数时,我无法求出平均数,以及哪些数字大于平均数,因为对于试图求出大于平均数的数字的部分,并非所有变量都是可见的。但是,当我允许这个部分看到所有的变量(don't But{}围绕某些部分)时,它会找到每一个数的平均值。现在,它为每个数字打印平均值,而为大于平均值的数字打

  • AVL树是一种平衡的二元搜索树,即高度=O(log(n))。这是通过确保每个节点都遵循AVL树属性来实现的: 左侧子树(LST)的高度-右侧子树(RST)的高度在[-1,0,1]范围内 其中,对于给定节点,高度(LST)-高度(RST)称为平衡因子(BF)。 根据这个定义,叶子的高度是0。但是几乎每次讨论AVL树时,人们都认为叶子的高度是1。 我的问题是,我们能把叶子的高度取为0吗?这将使以下BS

  • 对于这个任务,我认为我做对了,但是当我在网上提交时,即使我用Eclipse检查过,它也没有把它列为正确的。 提示: 写一个方法isPalinene,它接受一个Strings数组作为它的参数,如果该数组是回文(如果它向前读取和向后读取相同),则返回true,如果不是,则返回 /false。例如,数组{"alpha"、"beta"、"gamma"、"delta"、"gamma"、"beta"、"alp

  • 本文向大家介绍在C ++中找到盈亏平衡点的程序,包括了在C ++中找到盈亏平衡点的程序的使用技巧和注意事项,需要的朋友参考一下 输出结果

  • 问题内容: 我们需要打印数组中存在的所有leaders。如果元素大于元素的右侧,则元素是领导者。 例如: 问题答案: 使用两个循环。外循环迭代数组元素,内循环检查数组的正确元素。如果当前元素大于右侧元素,则它是leaders。 java代码: 时间复杂度:o(N^2) 解决方案2: 让我们找到更优化的解决方案 我们将使用最右边的元素始终是leaders的属性。 我们将从最右边的元素开始并跟踪最大值