以下转自http://www.ahathinking.com/archives/177.html
题二:给定一系列x轴的点坐标,例如 1,3,7,8,9,11这些坐标升序放在数组中,现在给一根绳子,长度为4,问绳子最多能覆盖的点数有多少,例如绳子放前面只能覆盖两个点,1,3,如果放
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int a[]=new int[]{1,3,7,8,9,11}; //int b[]=new int[]{2,4,1,1,2}; int b[]=new int[]{1,1,1,1}; int beg=0; int sum=0; int k=4;//固定值 4 int ans=0;//保存最长值 int temp = 0; for(int i=0;i<b.length;i++) { sum=sum+b[i] ; if(sum>=k) { if(sum==k) {temp=i-beg+1;System.out.println(i+":"+beg);} else temp=i-beg; if(ans<temp) ans=temp; sum-=b[beg]; beg++; } } System.out.println(ans+1);//输出阀盖点数 } }
我先给出了一种暴力方案,O(nm)的复杂度;之后想了一段时间给出了一个优化的O(n)思路,但是面试官说我的想法和方向都是对的,只是会有特例解决不了,到现在我也不知道特例是啥,最优的解法是什么,欢迎牛牛们留言指导。
一师兄给出方案:两个指针往前走,前面的负责加,后面的负责减,前面的每次都移动,如果点间隔长度大于绳子长度,后面指针移动。好方法啊<大拇指>;
题目和剑指向offe中从1到N中找到连续的何为固定值类似,其实也不难想,我们最基本的来看。
int a[]=new int[n];假设以这个数组当研究对象,值随便。最基本的想法便是枚举
int beg=0;
int end=0;
for(int i=0;i<n;i++) //枚举开始点
{
int sum=0;//和为0
for(int j=i;j<n;j++) //从开始点找到和为固定值的点值;
{
sum+=a[j];
if(sum==固定值) 输出结果;
if(sum>固定值) break;
}
}
这个是最原始的,很是好理解,专业说法就是可读性强,可是做了很多重复的计算,我么可以优化一下,就成了术中的代码了
int sum=0;
int beg=0;
//beg就是上文所说的头
//i就是模拟的尾巴
for(int i=0;i<n;i++)
{
sum= sum+a[i];
if(sum==固定值){ 输出结果 ,sum=sum-a[beg];beg++;}//以beg成功,以beg+1接着寻找。
if(sum>固定值) { sum=sum-a[beg]; beg++; }//以beg为头失败,所以以beg+1为头
}
}
在这道面试题目中,是小于等于4米的最大长度,其实是类似的,
int len=0;
for(int i=0;i<n;i++)
{
sum= sum+a[i];
if(sum==固定值){
输出结果 ,
sum=sum-a[beg]
if(temp>en) len=temp;
=i-beg+1;
if(temp>en) len=temp;
;
beg++;
int temp
int temp=i-beg+1;
}//以beg成功,以beg+1接着寻找。
if(sum>固定值) { sum=sum-a[beg]; beg++;
i
}//以beg为头失败,所以以beg+1为头
}
package 小于等于k; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int a[]=new int[]{1,3,7,8,9,11}; //int b[]=new int[]{2,4,1,1,2}; int b[]=new int[]{1,1,1,1}; int beg=0; int sum=0; int k=4;//固定值 4 int ans=0;//保存最长值 int temp = 0; for(int i=0;i<b.length;i++) { sum=sum+b[i] ; if(sum>=k) { if(sum==k) {temp=i-beg+1;System.out.println(i+":"+beg);} else temp=i-beg; if(ans<temp) ans=temp; sum-=b[beg]; beg++; } } System.out.println(ans+1);//输出阀盖点数 } }