【问题标题】:A zero-indexed array given & An equilibrium index of this array给定一个零索引数组和该数组的平衡索引
【发布时间】:2016-01-27 07:47:10
【问题描述】:

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

例如,考虑以下由 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

现在我要写一个函数:

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.

【问题讨论】:

  • 一种方法是依次遍历每个元素,并将其左右的元素相加,看看左右和是否相等:如果相等,那就是一个平衡点,你可以停下来;否则,移动到下一个元素并重试。尝试先实现它。对于大 N 来说效率不高,但这是一个开始。
  • 因为可以修改输入数组的元素。这就是为什么我们不需要专门限制数组
  • 从左右和开始。左边从零开始,右边是从索引 1 到 N-1 的项目的总和。从 1 到 N-2 循环遍历数组并将 N-1 值添加到左侧并减去 N+1 值到右侧。检查它们是否相等。如果是,则返回 N,否则继续。您还需要检查初始右和是否在开头为 0 并返回 0,或者左和是否在末尾为 0 并返回 N-1。
  • 哪种语言?例如,Java 有 ArrayList,但 C 和 C++ 没有。语言决定了可以轻松使用的数据结构。

标签: java c++ arrays algorithm data-structures


【解决方案1】:

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;
}

}

【讨论】:

    【解决方案2】:

    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;
    
    
        }
    }
    

    【讨论】:

    • 一点解释肯定会提高您的回答质量。
    【解决方案3】:

    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;
    }
    

    【讨论】:

      【解决方案4】:

      在 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;
      

      我觉得它不需要返回索引数组很奇怪;也就是说,如果您需要它,只需稍作修改就不太难实现

      【讨论】:

        【解决方案5】:

        答案发布在此博客中: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; 
        } 
        

        【讨论】:

          【解决方案6】:

          这是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));
          }
          

          【讨论】:

            【解决方案7】:

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

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

              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;
              

              }

            【讨论】:

              【解决方案8】:

              您可以使用求和方法来解决这个问题。只要左边的总和=右边的总和,你就有一个平衡点。

              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;
              }
              

              【讨论】:

                【解决方案9】:

                直截了当的方法如下所示。

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

                例如,如果你有 C++ 中的数组

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

                然后您可以使用普通循环来计算总和或标准算法std::accumulate在标题&lt;numeric&gt;中声明

                例如

                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
                

                【讨论】:

                  【解决方案10】:

                  我在 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
                  

                  }

                  【讨论】:

                    【解决方案11】:

                    在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;
                    

                    【讨论】:

                      【解决方案12】:

                      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
                      )
                      

                      【讨论】:

                        【解决方案13】:

                        简单的解决方案:
                        步骤:

                        1)检查(数组=空)

                        然后打印“No Equilibrium point present as the array is NULL”

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

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

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

                        循环(数组索引 1 到 Length-1)

                        将每个指标视为平衡点

                        检查(平衡点以下元素之和=平衡点以上元素之和)

                        是 => balance_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 
                         }
                        

                        【讨论】:

                          【解决方案14】:

                          对于懒人和 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)

                          【讨论】:

                            【解决方案15】:

                            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
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2014-02-18
                              • 1970-01-01
                              • 2021-08-27
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多