我是C语言的初学者,一直在尝试Leet代码的问题:
*Problem Statement: 给定一个0和1的字符串s,返回将字符串拆分为两个非空子串(即左子串和右子串)后的最大得分。
拆分字符串后的分数是左子串中的0的数量加上右子串中的1的数量 *
这是我的尝试:
c language
int maxScore(char* s) {
int length=strlen(s);
//int count_zero=0;
int arr[length];
int s_zero=0;
int s_one=0;
int sum=0;
for(int n=0;n<length;n++)
{
for(int i=0;i<=n;i++)
{
if(s[i]=='0')
{
s_zero+=1;
}
}
for(int j=n+1;j<length;j++)
{
if(s[j]=='1')
{
s_one+=1;
}
}
sum=s_zero+s_one;
arr[n]=sum;
s_zero=0;
s_one=0;
sum=0;
}
int ans=arr[0];
for(int i=0;i<length-1;i++)
{
for(int j=i+1;j<length;j++)
{
if(arr[i]>arr[j] && arr[i]>ans)
{
ans=arr[i];
}
}
}
return ans;
}
字符串
它已经通过了测试用例(100/104),但是当输入是'110000'时,它没有通过测试用例。它给出的输出是1而不是3。请告诉我我的代码哪里出错了。请记住,我是一个初学者,现在才开始接触C语言。
2条答案
按热度按时间7vhp5slm1#
for(int n=0;n<length;n++)
应该是n < length - 1
,因为在n=length-1
处拆分无效。1.(可选)使用单独的循环来对左右分区进行评分是非常好的,但是组合起来,它们会扫描所有的
s
,因此可以在单个循环中通过计算分割前的0(包括)n
和分割后的1(不包括)。1.(次要)在初始化
ans = arr[0]
时,for(int i=0;i<length-1;i++)
可以从i=1
开始。for(int j=i+1;j<length;j++)
不正确,因为arr[length-1]
不是有效的拆分(根据% 1.)。1.要找到一个数组的最大值
ans
,你只需要遍历它一次(O(n)
)。你有什么工作(除了4.),但它不必要地慢(O(n^2)
)。合并将以上所有内容结合起来,重新命名变量以供通用(
n
通常用于长度,i
和j
作为索引变量),您将得到此O(n^2)
算法:字符串
另一种方法是在数组
zero
中从左边开始累加0的计数。左边分区的分数是zero[i]
。右边位置的分数有n-i-1
个数字(0或1),所以我们需要减去有zero[n-1] - zero[i]
的0来找出有多少个1。这有O(n)
的运行时间:型
两种实现的输出都是:
型
64jmpszr2#
作为对Allan Wind的完整回答的补充,这里有一个替代实现。
我们的想法是先遍历字符串,确定其长度,并计算零的数量(如果左边的子串可能是整个字符串,则等于分数)。然后将拆分移动到左边,同时根据移动到右边子串的元素的值更新分数:
字符串