平衡数组索引,同时从左和右对数组求和

时间:2018-06-13 17:59:29

标签: c++ algorithm c++11 sum range

平衡指数问题:

输入一组n正整数

输出一个索引i,如果不存在这样的索引,则元素V[0]...V[i]的总和恰好等于v[i + 1]...V[n-1];或None的总和。例如:

[5,1,2,2] -> output i = 0

[1,1,1,1,1,1] -> output = 2

[2,2,2] -> output = None

一直坚持这个问题可以有人帮助基本逻辑吗?像这样的psuedocode。它的基本和简单。我只是没有完全理解逻辑。

for(int i = 0; i < size; i++)
{
    for(int j = i + 1; j < size; j++)
    {
        sum1 = array[i] + sum1
        sum2 = array[j] + sum2

        if(sum1 == sum2)
            return i; 
    }
}

4 个答案:

答案 0 :(得分:2)

使用std::accumulate,您可以执行以下操作。

#include <iostream>
#include <vector>
#include <numeric>
#include <cstddef>

int balanceIndex(const std::vector<int>& vec)
{
   for(std::size_t index = 0; index< vec.size(); ++index)
   {
      int left_sum = std::accumulate(vec.begin(), vec.begin() + index + 1, 0);
      int right_sum = std::accumulate(vec.begin() + index + 1, vec.end(), 0);
      if(left_sum == right_sum)
         return index;
   }
   return -1;
}

int main()
{
  std::vector<int> a = {5,1,2,2};
  std::vector<int> b = {1,1,1,1,1,1};
  std::vector<int> c = {2,2,2};

  int answer = balanceIndex(c);  //try for vectors b and c
  (answer != -1) ? std::cout<< answer : std::cout << "None\n";

  return 0;
}

更新:以上解决方案的时间复杂度为 O(n ^ 2)。正如@NicoSchertler在评论中提到的, O(n)解决方案可以如下:

int balanceIndex(const std::vector<int>& vec)
{
   int right_sum = std::accumulate(vec.begin(), vec.end(), 0);
   int left_sum = 0;
   for(std::size_t index = 0; index< vec.size(); ++index)
   {
      right_sum -= vec[index];
      left_sum  += vec[index];
      if(left_sum == right_sum) return index;
   }
   return -1;
}

答案 1 :(得分:2)

您可以先检查一个奇数数组,然后停止,而不是第二次通过所有数组。 这个算法是线性O(N)。

#include <iostream>
#include <vector>
#include <numeric>

int balanceIndex(const std::vector<int>& array)
{
    int sum = std::accumulate(array.begin(), array.end(), 0);

    if (sum % 2 == 1)
        return -1;

    int leftSum = 0;
    int halfSum = sum / 2;

    size_t index = 0;    
    while(leftSum < halfSum)
        leftSum += array[index++];

    if (leftSum == halfSum)
        return index-1;

    return -1;
}

int main()
{
    std::cout << balanceIndex({5, 1, 2, 2}) << std::endl;
    std::cout << balanceIndex({1, 1, 1, 1, 1, 1}) << std::endl;
    std::cout << balanceIndex({2, 2, 2}) << std::endl;

   return 0;
}

答案 2 :(得分:1)

C-Array方法:

#include <iostream>

using namespace std;

uint32_t sum(uint32_t arr[], uint32_t n)
{
    uint32_t s = 0;
    for (uint32_t i = 0; i < n; i++) {
        s += arr[i];
    }
    return s;
}

int32_t getIdx(uint32_t arr[], uint32_t n)
{
    uint32_t sum_l = 0;
    uint32_t sum_r = sum(arr, n);

    if ((sum_r%2) == 1) {
        return -1; //if the sum is odd, then sum(arr[0...i]) != sum(arr[i+1...n-1])
    }

    for (uint32_t i = 0; (i < n) && (sum_r > sum_l); i++) {
        sum_r -= arr[i];
        sum_l += arr[i];
        if (sum_r == sum_l) {
            return i;
        }
    }

    return -1;
}

int main()
{
    uint32_t arr1[] = {5, 1, 2, 2};
    cout << "{5, 1, 2, 2}: sum=" << sum(arr1, 4) << " idx=" << getIdx(arr1, 4) << endl;

    uint32_t arr2[] = {1, 1, 1, 1, 1, 1};
    cout << "{1, 1, 1, 1, 1, 1}: sum=" << sum(arr2, 6) << " idx=" << getIdx(arr2, 6) << endl;

    uint32_t arr3[] = {2, 2, 2};
    cout << "{2, 2, 2}: sum=" << sum(arr3, 3) << " idx=" << getIdx(arr3, 3) << endl;

    return 0;
}

答案 3 :(得分:-1)

至于理解问题:你正在搜索这样的索引i,i和i左边的数字总和是相等的,例如:

  

V = [1 2 3] - &gt; i = 1,因为V [0] + V [i = 1] = V [i + 1 = 2]

关于如何编写程序代码,我建议使用TDD方法,即根据我的示例进行首次写入测试;然后尝试编写通过此测试的函数。接下来编写更复杂的测试(例如,数字不会给你有效的i)