怎么算法版如此冷清?加温.REF:两个算法题,请教各位高手!

中间件XL 2007-01-20 11:56:53
本贴引自C/C++版 http://community.csdn.net/Expert/TopicView3.asp?id=5304123
其中第二题:
2.有一串数字,比如说:1,7,-5,9,13,-1,8,...,77 问,怎么设计一个比较好的算法,可以快速得到这串数字中最大的数字串,要求数字串必须是连续的!

本人觉得很有取,也有难度.我只用java,因此搬到这里比较合适.

以下是本人的拙解,欢迎各路英雄切磋,共同学习.
/*
第二题
原理:
设数字串a[]
设数组s[][],其中s[i][j]表示以i为起点,j个元素长的数字串。
则所有连续字符串为一上三角矩阵
s[1][1],s[1][2],...,s[1][n-1],s[1][n]
s[2][1],s[2][2],...,s[2][n-1]
...
s[i][1],s[i][2],...,s[i][n-i+1]
...
s[n][1].
n为数组个数

以下拿任一小三角型研究
(i,j) . . (i,j+1)
(i+1,j) .
3元素如下:
s[i][j],s[i][j+1]
s[i+1][j]
其中:
s[i][j+1]=s[i][j]+a[i+j+1]
s[i+1][j]=s[i][j]-a[i]+a[i][i+j+1]
得: s[i][j+1]=s[i+1][j]+a[i]
即: 小三角型斜线相邻两点相差a[i]
算法:
for each col{
以s[i][col]为起点计算斜线每个点
比较该点的值和当前最大值
}
参考代码: java
*/
class test{
public static void main(String args[]){
int a[]=new int[]{0,-1,6,-5,9,13,-1,8,-6}; // 第一个丢弃,只为与原理分析表示一致
int max=a[1]; // 最大值
int s=0;
int I=1,J=1;
int tmp,tmps;
for(int j=1;j<a.length;j++){
s=s+a[j]; // s[i][j] 斜线起点
max=(s>max) ? s:max;
if (max==s){
I=1;J=j;
}
tmps=s;
for(int i=1;i<=j-1;i++){
tmp=s-a[i]; // s[i+1][j]=s[i][j+1]-a[i]
max=(tmp>max) ? tmp:max;
if (max==tmp){
I=i+1;J=j;
}
s=tmp;
} // end for i
s=tmps;
} // end for j
System.out.println(I+","+J);
System.out.print(max);
}
}
...全文
530 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
AngkorAlone 2007-10-03
  • 打赏
  • 举报
回复

这是高中信息学的一个例题……
消除重复计算一部分的。
O(n)是存在的,使用前n项和的方法。
甚至只需要O(1)的存储——如果不考虑溢出的话。
tiancai1 2007-09-23
  • 打赏
  • 举报
回复
靠,题目都没有说清楚,要是按题目的意思,还要讨论!!
强烈建议,任何问题都必须把题目说清楚。
cymandhxl 2007-01-31
  • 打赏
  • 举报
回复
wanghui0380(放歌) ( ) 信誉:100 Blog
=============================
wanghui0380 2007-01-26
  • 打赏
  • 举报
回复
1.第一个题就是十进制转三进制,无聊
2.第二个问题更无聊,如果你把这个问题看成一个按时间序列一个振荡波,这样就形成了一个波形图,这个问题就成了计算最大波幅,如下图
1,7,-5,9,13,-1,8

1
8 //正向波动7,1+7=8
3 //负向波动5,8-5=3
12 //正向波动9 3+9=12
25 //正向波动13 12+13=25
24 //负向波动-1,25-1=24
32 //正向波动8 24+8=25
这样看一次循环就可以
wang430903 2007-01-26
  • 打赏
  • 举报
回复
#include <stdio.h>
int f(int *a)
{
int max,min,sum,max_i,min_i,temp,temp_i;
max=a[0]; min=sum=max_i=temp=0; min_i=temp_i=-1;
for(int i=0;i<8;i++)
{
sum+=a[i];
if(sum>max)
{
max=sum;
max_i=i;
if(temp_i<=max_i)
{
min_i=temp_i;
min=temp;
}
}
if(sum<min)
{
temp=sum;
temp_i=i;
}
}
printf("%d----%d:\n",min_i+2,max_i+1);
return (max-min);
}
void main()
{
int a[8]={-1,6,-5,9,13,-1,8,-6};
printf("%d\n",f(a));
}
wang430903 2007-01-26
  • 打赏
  • 举报
回复
for循环对数列求和,得到最大的和sum_max,以及所在的位置max_p
在for循环对第1到max_p个数求和得到最小的和sum_min,以及所在位置min_p
最终结果MAX=sum_max-sum_min 所在的位置为 min_p+1 个数到 max_p
kinkoyo 2007-01-22
  • 打赏
  • 举报
回复
这种规划我从来都是靠经验的,不会证明,数学还是不够好啊
ahjoe 2007-01-22
  • 打赏
  • 举报
回复
2.有一串数字,比如说:1,7,-5,9,13,-1,8,...,77 问,怎么设计一个比较好的算法,可以快速得到这串数字中最大的数字串,要求数字串必须是连续的!

好深奥的题目!朕看不懂。
mathe 2007-01-21
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/5122/5122654.xml
mathe 2007-01-21
  • 打赏
  • 举报
回复
这道题目算法版早就讨论过了,O(n)的时间。
houdy 2007-01-20
  • 打赏
  • 举报
回复
对于这个算法,通常情况下,我们可以得到O(n^2)时间复杂度的算法。
<编程珠玑,第二版>中的第8个专栏正好是涉及到这个问题,里面提供了一个O(n)时间复杂度的算法。
对于这样的问题,如果要做到O(n)的时间复杂度,需要注意几点:
1.不能进行多重镶套遍历,这样时间复杂度一定超过O(n)
2.注意"备份"前一次操作的结果,不要每次都处理类似的内容
具体的还是看书吧。
中间件XL 2007-01-20
  • 打赏
  • 举报
回复
测试:
数据: {-1,6,-5,9,13,-1,8,-6}
结果: 2,7 // 2~7的字串
30
数据: {1,6,-5,9,13,-1,8,-6}
结果: 1,7 // 2~7的字串
31
通过.
中间件XL 2007-01-20
  • 打赏
  • 举报
回复
O(n)真没想到,好,找书看看

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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