给定的零索引数组 &该数组的均衡索引

A zero-indexed array given & An equilibrium index of this array

本文关键字:数组 索引      更新时间:2023-10-16

给出了一个由 N 个整数组成的零索引数组 A。该数组的平衡指数是任何整数 P,使得 0 ≤ P <N,较低索引的元素之和等于较高索引的元素之和,即A[0]>

例如,考虑以下由 N = 8 个元素组成的数组 A:

  A[0] = -1
  A[1] =  3
  A[2] = -4
  A[3] =  5
  A[4] =  1
  A[5] = -6
  A[6] =  2
  A[7] =  1

P = 1 是这个数组的平衡指数,因为:

A[0] = −1 = A[2] + A[3] + A[4] + A[5] + A[6] + A[7]

P = 3 是这个数组的平衡指数,因为:

A[0] + A[1] + A[2] = −2 = A[4] + A[5] + A[6] + A[7]

P = 7 也是一个平衡指数,因为:

A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] = 0

并且没有索引大于 7 的元素。

P

= 8 不是均衡指数,因为它不满足条件 0 ≤ P <N。>

现在我必须编写一个函数:

int solution(int A[], int N);

给定一个由 N 个整数组成的零索引数组 A,返回其任何均衡索引。如果不存在平衡指数,则该函数应返回 −1。

例如,给定上面显示的数组 A,该函数可能返回 1、3 或 7,如上所述。

假设:

N is an integer within the range [0..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].

这里有一些复杂性:

Elements of input arrays can be modified.

> 100% - Java

int solution(int A[], int N) {
    long sum = 0;
    for (int i = 0; i < A.length; i++) {
        sum += (long) A[i];
    }
    long leftSum = 0;
    long rightSum = 0;
    for (int i = 0; i < A.length; i++) {
        rightSum = sum - (leftSum + A[i]);
        if (leftSum == rightSum) {
            return i;
        }
        leftSum += A[i];
    }
    return -1;
}

}

100% 使用 C# 得分

using System;
class Solution {
    public int solution(int[] A) {
        // First calculate sum of complete array as `sum_right`
        long sum_right = 0;
        for (int i = 0; i < A.Length; i++)
        {
            sum_right += A[i];
        }
        // start calculating sum from left side (lower index) as `sum_left`
        // in each iteration subtract A[i] from complete array sum - `sum_right`
        long sum_left = 0;
        for (int p = 0; p < A.Length; p++)
        {
            sum_left += p - 1 < 0 ? 0: A[p-1];
            sum_right -= A[p];
            if (sum_left == sum_right)
            {
                 return p;
            }
        }
        return -1;

    }
}

Javascript 中的 100 分

function solution(V) {
    var sum = 0;
    for (i=0; i < V.length; i++) {
      sum += V[i];   
    }
    var leftSum= 0;
    var rightSum = 0;
    for (j=0; j < V.length; j++) {
      rightSum = sum - (leftSum + V[j]);
      if(leftSum == rightSum) {
          return j;
      }
      leftSum += V[j];
    }
    return -1;
}

> 在C++中(因为这是原始标签之一,尽管看起来它已被删除......

int solution(int a[], int N){
    int left;
    int right;
    for(int i = 0; i < N; i++){
        left  = 0;
        right = 0;
        for(int t = 0; t < N; t++){
            if(t < i)      left  += a[t];
            else if(t > i) right += a[t];
            else continue;
        }
        if(left == right) return i;
    }
    return -1;
}
...
int demo[] = {-1, 3, -4, 5, 1, -6, 2, 1};
cout << solution(demo,sizeof(demo)/sizeof(*demo));

如果您想查看所有索引...

if(left == right) cout << "Equilibrium Index: " <<  i << endl;

我觉得很奇怪,它不需要返回索引数组;也就是说,如果你需要它,通过一些轻微的修改来实现它并不难

答案发布在此博客中:http://blog.codility.com/2011/03/solutions-for-task-equi.html。为了避免 O(N^2( 并实现 O(N( 性能:改善运行时间的关键观察是在恒定时间内更新左/右和,而不是从头开始重新计算它们。

int equi(int arr[], int n) 
{
    if (n==0) return -1; 
    long long sum = 0;
    int i; 
    for(i=0;i<n;i++) sum+=(long long) arr[i]; 
    long long sum_left = 0;    
    for(i=0;i<n;i++) {
        long long sum_right = sum - sum_left - (long long) arr[i];
        if (sum_left == sum_right) return i;
        sum_left += (long long) arr[i];
    } 
    return -1; 
} 

这是 java 等效

public static int equilibriumIndex(int[] array) {
    int INDEX_NOT_FOUND = -1;
    int rSum = 0, lSum = 0;
    for (int index = 0; index < array.length; index++) {
        rSum += array[index];           
    }
    for (int index = 0; index < array.length; index++) {
        lSum += (index==0) ? 0 : array[index -1];// cumulative sum before (left sum) the current index
        rSum -= array[index]; // sum after (right sum) the current index onwards
        if (lSum == rSum) { // if both sums, cumulative sum before the current index and cumulative sum after the current index is equal, we got the equilibrium index 
            return index;
        }                       
    }
    return INDEX_NOT_FOUND;
}

以下是测试方法

@Test
public void equilibriumTest() {
    int result = ArrayUtils.equilibriumIndex(new int[]{1,2,3,1,6});
    assertThat(result, equalTo(3));
}

动态编程方法。O(N( 时间。O(2N( 空间。

  1. 保留两个表(数组(,表之前和表之后。
  2. tableBefore 对每个 i 求和索引 i;i -> 1 到 N。
  3. tableAfter 对每个 i 求和索引 i;i -> N 到 1。
  4. 之后循环并比较表之前和表后中的每个索引。如果相等,那就是你的均衡指数。

    public static int EquilibriumIndex2(int[] a) {
    int len = a.length;
    int[] tableBefore = new int[len];
    int[] tableAfter = new int[len];
    tableBefore[0] = 0;
    for (int i = 1; i < len; i++) {
        tableBefore[i] = tableBefore[i - 1] + a[i - 1];
    }
    //System.out.println("tableBefore: " + Arrays.toString(tableBefore));
    tableAfter[len - 1] = 0;
    for (int i = len - 2; i >= 0; i--) {
        tableAfter[i] = tableAfter[i + 1] + a[i + 1];
    }
    //System.out.println("tableAfter: " + java.util.Arrays.toString(tableAfter));
    for (int j = 0; j < len; j++) {
        if (tableAfter[j] == tableBefore[j]) {
            return j;
        }
    }
    return -1;
    

    }

您可以使用sums方法来解决此问题。每当左边的总和=右边的总和时,你就有一个平衡点。

public int solution(int[] A) {
    int[] sumLeft = new int[A.length];
    int[] sumRight = new int[A.length];
    sumLeft[0] = A[0];
    sumRight[A.length-1] = A[A.length-1];
    for (int i=1; i<A.length; i++){
        sumLeft[i] = A[i] + sumLeft[i-1];
    }
    for (int i=A.length-2; i>=0; i--) {
        sumRight[i] = sumRight[i+1] + A[i];
    }
    for (int i=0; i<A.length; i++) {
        if (sumLeft[i]==sumRight[i]) {
            return i;
        }
    }
    return -1;
}

简单的方法如下所示。

首先,您需要计算数组所有元素的总和

例如,如果数组位于C++

int a[] = { -1, 3, -4, 5, 1, -6, 2, 1 };

然后,您可以使用普通循环来计算在标头<numeric>中声明的总和或标准算法std::accumulate

例如

long long int right_sum = 
    std::accumulate( std::begin( a ), std::end( a ), 0ll );

左子序列的元素之和最初等于零

long long int left_sum = 0;

然后,您可以使用适当的lambda表达式应用标准算法std::find_if,或者再次编写一个普通循环,例如

for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
    right_sum -= a[i];
    if ( left_sum == right_sum ) std::cout << i << ' ';
    left_sum += a[i];
}

结果将是

1 3 7

我在 Swift 3.0 中的答案

public func solution(_ A : inout [Int]) -> Int {
var nElements = A.count
var equilibriumIndexArray = [Int]() /* to store all possible indices */
var equilibriumIndex = -1
for fixedIndex in 0..<nElements{
    var sumLeft = 0
    var sumRight = 0
    //Sum the left part
    for index in 0..<fixedIndex
    {
        sumLeft += A[index]
    }
    //Sum the right part
    for index in fixedIndex+1..<nElements
    {
        sumRight += A[index]
    }
    //Check for equilibrium
    if sumLeft == sumRight
    {
        equilibriumIndexArray.append(fixedIndex)
    }
}
//pick a random element from the list of possible answers
if equilibriumIndexArray.count > 0
{
    let randomIndex = Int(arc4random_uniform(UInt32(equilibriumIndexArray.count)))
    equilibriumIndex = equilibriumIndexArray[randomIndex]
}
return equilibriumIndex

}

in python :)

def solution(A):
    INDEX_NOT_FOUND = -1
    right_sum = 0 
    left_sum = 0
    for item in range(0, len(A)):
        right_sum += A[item]
    for item in range(0, len(A)):
        if item == 0:
            left_sum +=  0 
        else: 
            left_sum += A[item -1]
        right_sum -= A[item]
        if left_sum == right_sum:
            return item
    return INDEX_NOT_FOUND;

100% - PHP

function solution(array $a)
{
    $result = [];
    for($i = 0; $count = count($a), $i < $count; $i++) {
        if(sumLeft($a, $i-1) === sumRight($a, $i+1)) {
            $result[] = $i;
        }
    }
    return  count($result) ? $result : -1;
}
function sumRight(array $a, int $position): int
{
    return array_sum(array_slice($a, $position));;
}
function sumLeft(array $a, int $position): int
{
    return array_sum(array_slice($a, 0, $position + 1));
}
echo "<pre>";
print_r(solution([-1, 3, -4, 5, 1, -6, 2, 1]));

输出:

Array
(
    [0] => 1
    [1] => 3
    [2] => 7
)

简单的解决方案:
步骤:

1( 检查(数组 = 空(

然后打印"不存在平衡点,因为数组为 NULL"

2( 检查(数组长度 = 1(

然后打印"Equilibrium_Index = 0" => 数组中仅存在单个元素,这是平衡点

3( 检查(数组长度> 1(

循环(数组索引 1 到长度 1(

将每个指数视为平衡点

检查(低于平衡点的元素之和 = 高于平衡点的元素之和(

是 => equilibrium_index = i (打破循环(

否 => 使用循环计数器的下一个值继续步骤 3

4( 如果从步骤 3 返回控制,则表示循环中不存在平衡点

然后打印"阵列中不存在平衡点"。

请在下面找到相同的代码:

 public int findSum(int equillibrium,int a[],int flag)
 {

      /*Flag - It represents whether sum is required for left side of equilibrium 
       point or right side of equilibrium point
      *Flag = 0 => Sum is required for left side of equilibrium point
      *Flag = 1 => Sum is required for right side of equilibrium point
      */
     int lowlimit = 0, uplimit = a.length-1, i ,sum = 0;
     if(flag==0)
         uplimit = equillibrium - 1;
     else
         lowlimit = equillibrium + 1;
     for(i=lowlimit ; i<=uplimit; i++)
         sum = sum + a[i];
     return sum;
 }
 public int findEquillibriumPoint(int a[])
 {
     int i = 0; //Loop Counter
     //Since only one element is present it is at equilibrium only and index of equillibrium point is index of single element i.e 0
     if(a.length==1)
         return 0;
     else
     {
         for(i=1;i<a.length;i++)
         {
             if(findSum(i,a,0)==findSum(i,a,1)) //checking if some of lower half from equilibrium point is equal to sum of upper half
                 return i; //if equilibrium point is found return the index of equilibrium point
         }
     }
     return -1;//if equilibrium point is not present in array then return -1 
 }

对于懒惰的人和PHP开发人员:

$A = [];
$A[0] = -1;
$A[1] =  3;
$A[2] = -4;
$A[3] =  5;
$A[4] =  1;
$A[5] = -6;
$A[6] =  2;
$A[7] =  1;
echo solution($A) . "n";
function solution($A)
{
    $sum = 0;
    for ($i=0; $i < count($A); $i++) {
        $sum += $A[$i];
    }
    $sumRight = 0;
    $sumLeft = 0;
    for ($j=0; $j < count($A); $j++) {
        $sumRight = $sum - ($sumLeft + $A[$j]);
        if ($sumLeft == $sumRight) {
            return $j;
        }
        $sumLeft += $A[$j];
    }
    return -1;
}

复杂性O(N)

100 分 Ruby

def equilibrium(a)
  sum = 0
  n = a.length
  left_sum = 0
  right_sum = 0
  n.times do |i|
    sum += a[i]
  end
  n.times do |i|
    right_sum = sum - left_sum - a[i]
    if right_sum == left_sum
      return i
    end
    left_sum += a[i]
  end
  return -1
end

经过全面测试的 C#

using System;

class Program
{
    static int Function1(int[] arr, int n)
    {
        int i, j;
        int leftsum;
        int rightsum;
        for (i = 0; i < n; ++i)
        {
            leftsum = 0;
            rightsum = 0;
            if(i == 0)
            {
                leftsum = 0;
                
                for (j = 0; j < n; j++)
                {
                    rightsum += arr[j];
                }
                if (leftsum == rightsum)
                    return i;
            }
            
                for (j = 0; j < i; j++)
                {
                    leftsum += arr[j];
                }
           
            if (n-1 != j)
            {
                for (j = i + 1; j < n; j++)
                {
                    rightsum += arr[j];
                }
            }
            else
            {
                rightsum = arr[n-1];
            }
            if (leftsum == rightsum)
                return i;
        }
        return -1;
    }
    public static void Main(string[] args)
    {
        int[] arr = { 1, 5, -8, 0, -2 };
        int arr_size = arr.Length;
        Console.Write(Function1(arr, arr_size));
    }
}