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

通过移除子数组使数组左右边和相等

皇甫繁
2023-03-14

查找子数组的开始索引和结束索引以使给定数组的左右边和相等的C程序。如果不可能,打印-1。我需要它为任何数组工作,这只是为了测试。这是一个找到平衡的密码。

#include <stdio.h> 

int equilibrium(int arr[], int n) 
{ 
int i, j; 
int leftsum, rightsum; 

/* Check for indexes one by one until 
an equilibrium index is found */
for (i = 0; i < n; ++i) {    

    /* get left sum */
    leftsum = 0; 
    for (j = 0; j < i; j++) 
        leftsum += arr[j]; 

    /* get right sum */
    rightsum = 0; 
    for (j = i + 1; j < n; j++) 
        rightsum += arr[j]; 

    /* if leftsum and rightsum are same, 
    then we are done */
    if (leftsum == rightsum) 
        return i; 
} 

/* return -1 if no equilibrium index is found */
return -1; 
} 

// Driver code 
int main() 
{ 
int arr[] = { -7, 1, 5, 2, -4, 3, 0 }; 
int arr_size = sizeof(arr) / sizeof(arr[0]); 
printf("%d", equilibrium(arr, arr_size)); 

getchar(); 
return 0; 
}

共有1个答案

周鸿云
2023-03-14

您可以在O(NlogN)O(N)(一般情况下)中解决此问题。

首先,您需要进行预处理,将从右到左的所有和保存在一个数据结构中,特别是一个平衡的二叉搜索树(例如红黑树、AVL树、Splay树等,如果可以使用stdlib,只需使用std::multiset)或一个HashTable(stdlib中是std::unordered_multiset):

void preProcessing(dataStructure & ds, int * arr, int n){
    int sum = 0;
    int * toDelete = (int) malloc(n)
    for(int i = n-1; i >= 0; --i){
        sum += arr[i];
        toDelete[i] = sum; // Save items to delete later.
        tree.insert(sum);
    }

因此,要解决这个问题,只需遍历数组一次:

// It considers that the deleted subarray could be empty
bool Solve(dataStructure & ds, int * arr, int n, int * toDelete){
    int sum = 0;
    bool solved = false; // true if a solution is found
    for(int i = 0 ; i < n; ++i){ 
        ds.erase(toDelete[i]); // deletes the actual sum up to i-th element from data structure, as it couldn't be part of the solution.
                               // It costs O(logN)(BBST) or O(1)(Hashtable)
        sum += arr[i];
        if(ds.find(sum)){// If sum is in ds, then there's a leftsum == rightsum
                         // It costs O(logN)(BBST) or O(1)(HashTable)
            solved = true;
            break;
        }
    }
    return solved;
}

然后,如果您使用BBST(平衡二进制搜索树),您的解决方案将是O(NlogN),但是,如果您使用HashTable,您的解决方案平均将是O(N)。我不会实现它,所以可能有一个bug,但我试图解释主要思想。

 类似资料:
  • 我已经完成了下面的编程练习:数组的等边。声明如下: 您将得到一个整数数组。您的任务是取这个数组并找到一个索引N,其中N左边的整数之和等于N右边的整数之和。如果没有索引可以做到这一点,则返回-1。 注意:如果给你一个数组有多个答案,返回最低正确的索引。 我已经阅读了用户Jenspiegsa提供的以下答案。这里有它的链接。 我想知道是否有一种方法来代替循环整个Instream过滤,其中左和右子数组是相

  • 我有两个8位数的十六进制字符串。我需要对这两个十六进制字符串应用和操作,然后应用右移位到7位,并得到十进制值。我尝试将十六进制字符串转换为长度为4的字节数组(8*2=32位=4字节),并按相同的顺序对各个字节执行&操作,将结果保存到另一个长度为4的byre数组中。如何对这个字节数组进行位移位? 以及data1Bytes和data2Bytes之间的操作,该操作给出输出:bytearray1[0,0,

  • 我想检查是否可以将一个数组拆分为具有相同和的连续子数组。拆分数组还意味着删除数组的边框元素。 例如,要将其拆分为3个部分,我们需要删除到元素 通过删除这2个元素,就有3个相同和的连续子数组,和。 因此,如果可以将数组拆分为3个部分(等和)并删除它们之间的边界,则应返回true,否则应返回false。 返回的示例是。因为删除2个元素后,它将有4个元素,这些元素不能分组为3个相等的和 我不知道如何处理

  • 我想用相当复杂的方案更新文档。 我想用原子更新来做(而不是在内存中修改它,然后调用.save())。 }); ////////////////////////////////////////////////////////////// 我有事件id(_id)、会话(id)和需要添加/删除项到投票人数组。

  • 我是java新手,我有任务要做——mergeSort,但我有一个老师根据数组右侧提出的问题,但我不知道该怎么做。这是我的代码: 代码运行得很完美,但是,正如我前面提到的,我的老师问我:“你处理一半的合并-请注意,你还有第二个数组(右边的一个),当左边的一个为空时,可能会有元素”。 你能告诉我我在这里做错了什么吗?谢谢你的帮助。