【发布时间】:2011-09-11 20:33:04
【问题描述】:
给定一个由 0 和 1 组成的数组,找到最大子数组,使得 0 和 1 的数量相等。 这需要在 O(n) 时间和 O(1) 空间内完成。
我有一个算法,它在 O(n) 时间和 O(n) 空间内完成。它使用前缀和数组并利用这样一个事实,即如果 0 和 1 的数量相同,则 sumOfSubarray = lengthOfSubarray/2
#include<iostream>
#define M 15
using namespace std;
void getSum(int arr[],int prefixsum[],int size) {
int i;
prefixsum[0]=arr[0]=0;
prefixsum[1]=arr[1];
for (i=2;i<=size;i++) {
prefixsum[i]=prefixsum[i-1]+arr[i];
}
}
void find(int a[],int &start,int &end) {
while(start < end) {
int mid = (start +end )/2;
if((end-start+1) == 2 * (a[end] - a[start-1]))
break;
if((end-start+1) > 2 * (a[end] - a[start-1])) {
if(a[start]==0 && a[end]==1)
start++; else
end--;
} else {
if(a[start]==1 && a[end]==0)
start++; else
end--;
}
}
}
int main() {
int size,arr[M],ps[M],start=1,end,width;
;
cin>>size;
arr[0]=0;
end=size;
for (int i=1;i<=size;i++)
cin>>arr[i];
getSum(arr,ps,size);
find(ps,start,end);
if(start!=end)
cout<<(start-1)<<" "<<(end-1)<<endl; else cout<<"No soln\n";
return 0;
}
【问题讨论】:
-
我想知道如果您想象零已被替换为负一,这样做是否更容易。这样子数组的总和为零。
-
我们可以修改原始数组吗?
-
这是获得 O(1) 的一个选项。但是有更好的方法吗?
-
既然这是一个家庭作业,我们可以假设有一个 O(1) 的存储解决方案吗?
-
您发布的算法似乎不正确。输入 4 作为大小,输入 1, 1, 1, 0 作为数组数据,你会发现答案是没有解决方案。原因在于
if(a[start]==0 && a[end]==1)和if(a[start]==1 && a[end]==0)行。a这里引用了前缀 sum 数组;我相信您打算让它参考原始数据。确实,条件a[start]==1 && a[end]==0是不可能的;因为start < end并且数组中没有元素是负数,所以直到start的前缀总和不能大于直到end。
标签: arrays algorithm binary-data