面试问题,求助

seaor 2008-10-08 02:26:15
一个数组所有数均为正,找出和最大的子集,要求没有任何两个数是相邻的
例如:
i) 3 2 7 10 结果是 13 ( 3 and 10)

ii) 3 2 5 10 7 结果是 15 (sum of 3, 5 and 7)
...全文
603 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
daidodo 2008-10-10
  • 打赏
  • 举报
回复
mark
xiao9900 2008-10-10
  • 打赏
  • 举报
回复
递归问题真是难懂,有没有好懂的教材
IT__Man 2008-10-10
  • 打赏
  • 举报
回复

#include "stdio.h"
int GetMaxValue(int *pArray,int iArrayNum);

int main(int argc, char* argv[])
{
int iArray[] = {1,8,5,7,10,9,6,3};

int iMaxValue = GetMaxValue(iArray,sizeof(iArray)/sizeof(int));
printf("%d\n",iMaxValue);
return 0;
}

int GetMaxValue(int *pArray,int iArrayNum)
{
// printf("iArrayNum = %d\n",iArrayNum);
if (iArrayNum <= 3)
{
if (iArrayNum == 3)
{
return (pArray[0] + pArray[2] > pArray[1] ? pArray[0]+ pArray[2] : pArray[1]);
}
else if (iArrayNum == 2)
{
return (pArray[0] > pArray[1] ? pArray[0] : pArray[1]);
}
else
return pArray[0];
}

int iTmpI = pArray[0]+GetMaxValue(pArray+2,iArrayNum-2);
// printf("iTmpI = %d\n",iTmpI);
int iTmpII = pArray[1]+GetMaxValue(pArray+3,iArrayNum-3);
// printf("iTmpII = %d\n",iTmpII);
return iTmpI > iTmpII ? iTmpI : iTmpII;
}
frank_ll 2008-10-09
  • 打赏
  • 举报
回复
这个题很难
xf_pan 2008-10-09
  • 打赏
  • 举报
回复
找出最大的三个数~~(相等的情况得考虑)
并记录下这三个数的位置,,
求出其中两个不相邻的数的和,,
这应该是最简单的方法了。。
csucj 2008-10-09
  • 打赏
  • 举报
回复
Up!
qin529 2008-10-09
  • 打赏
  • 举报
回复
1楼明显有问题,题目要求是所有数都不相邻
glacier3d 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 luansxx 的回复:]
递归的想法很对,其实前面我已经给过了相似的答案了,在8楼和12楼,你恐怕没仔细看。
[/Quote]

果然,而且你的实现更简洁,我把递归阶数增加了一阶,而且计算顺序的相反导致了函数的递归。学习中!
智物客 2008-10-09
  • 打赏
  • 举报
回复
貌似算法问题,遇到O(n^N)的解决方法暂时舍弃。
Fighting Horse 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 glacier3d 的回复:]
看了前面各位的回答,貌是没有是对的,随便举个反例,比如3,2,1,9这个序列,我发现就求得结果不是12。
下面是我的c++递归实现:

C/C++ code
#include <iostream>
#include <fstream>
using namespace std;

int data[200];
int datacnt;

int maxsum(int *p, int n)
{
if(n <= 0) return 0;
else if(n == 1) return *p;
else if(n == 2)
{
if(*p > *(p+1)) return *p;

[/Quote]

递归的想法很对,其实前面我已经给过了相似的答案了,在8楼和12楼,你恐怕没仔细看。
cy19840408 2008-10-09
  • 打赏
  • 举报
回复
#define N 100

subIntarray()
{
int i,j,k;
int iIntarray[N];
int iSubIntFlag[N];
int iMeetCondSubIntFlag[N];
int iSum = 0;
int iTempSum = 0;

memset(iSubIntFlag,0,N);
memset(iMeetCondSubIntFlag,0,N);
for(i = 0; i< N /2 + 1; i++ )
{
memset(iSubIntFlag,0,N);
iTempSum = iIntarray[i];

for (j=i+2; j< N; j++)
{
memset(iSubIntFlag,0,N);
iSubIntFlag[i] = 1;

for(k=j;k< N;k += 2)
{
iSubIntFlag[k] = 1;
iTempSum = iTempSum + iIntarray[k];
}

if (iTempSum > iSum)
{
memcpy(iMeetCondSubIntFlag, iSubIntFlag, N);
iSum = iTempSum;
}
}
}

for(i=0 ;i< N;i++)
{
if (iMeetCondSubIntFlag[i] == 1)
{
printf("%d,",iIntarray[i]);
}
}

printf("sum=%d\n",iSum);
}



只要N>=3的都可以,小于3的各位再修改一下就行了,上面算法还有点罗嗦,还可以油画。
glacier3d 2008-10-09
  • 打赏
  • 举报
回复
看了前面各位的回答,貌是没有是对的,随便举个反例,比如3,2,1,9这个序列,我发现就求得结果不是12。
下面是我的c++递归实现:

#include <iostream>
#include <fstream>
using namespace std;

int data[200];
int datacnt;

int maxsum(int *p, int n)
{
if(n <= 0) return 0;
else if(n == 1) return *p;
else if(n == 2)
{
if(*p > *(p+1)) return *p;
else return *(p+1);
}
else
{
int sum1, sum2;
sum1 = *p + maxsum(p+2, n-2);
sum2 = *(p+1) + maxsum(p+3, n-3);

if(sum1 > sum2) return sum1;
else return sum2;
}
}

int main()
{
ifstream fin("data.txt");
fin>>datacnt;
int i;
for(i=0; i<datacnt; i++) fin>>data[i];
int ms = maxsum(data, datacnt);
cout<<ms<<endl;

fin.close();
system("pause");
return 0;
}


这样实现是有理论支持的,可不是胡想的。

基本思想:
考虑数列:a1,a2,a3,...,an,其最大的元素不相邻子集中肯定含有a1或者a2(对吧?要不会与和最大矛盾),所以问题递归为a1 + max_subset_sum(a3,a4,...,an)与a2 + max_subset_sum(a4,a5,...,an)这两个值中取最大值。然后,继续用同样思想分别递归max_subset_sum(a3,a4,...,an) 与 a2 + max_subset_sum(a4,a5,...,an),.....
最终,就可获得最大值。

当然,在递归的过程中含可以保存具体的子集元素,但那需要保存许多中间信息,相对麻烦点!


大家看看我这种算法是否有道理!
Fighting Horse 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 sonepiece 的回复:]
#include <iostream>
using namespace std;
const int SIZE=10;

int maxSum(int a[])
{
int sum = 0;
int tempsum,j;

for (int i=0;i <SIZE-2;i++)
{
tempsum = a[i];

for (j=i+2;j <SIZE;j++)
{
tempsum +=a[j];
if (tempsum > sum)
{
sum = tempsum;
}


[/Quote]

你这只是两个数的和,题目的意思是可以取多个数字,和31楼的差不多
lufy_sun 2008-10-09
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;
const int SIZE=10;

int maxSum(int a[])
{
int sum = 0;
int tempsum,j;

for (int i=0;i<SIZE-2;i++)
{
tempsum = a[i];

for (j=i+2;j<SIZE;j++)
{
tempsum +=a[j];
if (tempsum > sum)
{
sum = tempsum;
}

tempsum =a[i];
}
}

return sum;

}

int main()
{
int a[SIZE]={1,2,3,4,5,6,4,5,6,8};
int max;
max=maxSum(a);
cout<<max<<endl;
system("pause");
return 0;
}
这样就可以了
lufy_sun 2008-10-09
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;
const int SIZE=10;

int maxSum(int a[])
{
int sum = 0;
int tempsum,j;

for (int i=0;i<SIZE-2;i++)
{
tempsum = a[i];

for (j=i+2;j<SIZE;j++)
{
tempsum +=a[j];
if (tempsum > sum)
{
sum = tempsum;
}

tempsum =a[i];
}
}

return sum;

}

int main()
{
int a[SIZE]={1,2,3,4,5,6,4,5,6,8};
int max;
max=maxSum(a);
cout<<max<<endl;
system("pause");
return 0;
}
这样就可以了
gentlelotus 2008-10-09
  • 打赏
  • 举报
回复
应该存在线性复杂度的解法。不知道这个问题是否有什么现实的实用价值。
matrixdwy 2008-10-09
  • 打赏
  • 举报
回复
额。。。的确有这个问题
southbirdfly 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 matrixdwy 的回复:]
我昨天睡觉前想了一下,觉得这个问题其实还是很简单的
首先对这些数字进行排序,时间O(N2)

如果元素个数为偶数,那么就取第2,4,6,8,...,N个元素,结果肯定最大

如果元素个数N为基数,那就麻烦点
取第1,3,5,7,9...N个元素
和第2,4,6,8,...N-1个元素的总合 作比较
[/Quote]

排序后原来的次序不是改变了吗??这样第2、4、6....原来可能是相邻的?
matrixdwy 2008-10-09
  • 打赏
  • 举报
回复
我昨天睡觉前想了一下,觉得这个问题其实还是很简单的
首先对这些数字进行排序,时间O(N2)

如果元素个数为偶数,那么就取第2,4,6,8,...,N个元素,结果肯定最大

如果元素个数N为基数,那就麻烦点
取第1,3,5,7,9...N个元素
和第2,4,6,8,...N-1个元素的总合 作比较
asksgp 2008-10-09
  • 打赏
  • 举报
回复
越看越复杂,好像不只两个数的和。
加载更多回复(34)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧