前几天回家姐夫给我出了三道面试题(新手难度);
题目
1.给定一个有序数列,求value在第一次出现的位置(数据重复度比较高)
第一反应就是二分查找,然后再往前找一段。(被姐夫pass掉了,要我再优化一下);
题目不难,二分思想没错,在此基础上我进一步二分,就行了(感觉自己算法题白写了,这都要想这么久);
代码:(来源于姐夫);
int fun(vector<int> arr,int n)
{
int last=-1;
int l=0,r=arr.size()-1;
while(l<=r)
{
int mid=(l+r)/2;
if(arr[mid]<n)
l=mid+1;
else if(arr[mid]>n)
r=mid-1;
else
{
last=mid;
r=mid-1;
}
}
return last;
}
2.给定一个无序数列,求第k大的数值
我的第一反应是用堆排序然后直接pop()k次就行了;(空间浪费时间浪费!!!)
第一次优化:维护一个大小为k的堆就行了,最后也只要取堆顶的元素;(比上一个算法快了一点,在空间上优化较大,时间上差异不大);
第二次优化:在快排的基础上一边排序一边查找,就是快排的一个变型;
代码:(本人代码,肯定还有许多bug,凑合着用一下)
int quicksort(vector<int> arr,int k,int left,int right)
{
int i,j,t,tmp;
tmp=arr[left];
i=left,j=right;
while(i!=j)
{
while(arr[j]>=tmp&&i<j) j--;
while(arr[i]<=tmp&&i<j) i++;
if(i<j)
Swap(&arr[i],&arr[j]);
}
Swap(&arr[i],&arr[left]);
if(i<k)
return quicksort(arr,k,i+1,right);
else if(i>k)
return quicksort(arr,k,left,i-1);
else
return arr[k];
}
分析一下时间和空间复杂度;
第一种情况: 时间O(nlogn),空间O(n);
第二种情况: 时间O(nlogk),空间O(k);
第三种情况: 时间O(n),空间 O(n);
3.飞机加油问题:现有一架飞机要绕地球飞一圈,但是单次再油只够其飞行1/4圈,问最少需要多少辆飞机同时同地起飞才能使一架飞机飞完一圈(假设飞机在飞行途中可以自由换油且无损耗)
当时想了挺久的,后来有了一点思路,2架飞机同时起飞可以让1架飞机飞到1/8点处(其中一架满油,另一架坠毁了);由此类推4架生2架,2架再前进1/8牺牲一架,由此答案是2^6架飞机就可以;
以上思路是有问题的,这样不能保证所用的飞机最少,想一想也知道为什么,其中很多油量的浪费;
其实自习想想也挺简单的,只要保证油量浪费最少就行了,保证1架飞机供油,其他飞机一直处于满油状态,然后在3/4处有1架满油的飞机就行了;
设有n架飞机同时起飞,第1架飞机坠落点在m处,则mn=1/4,m=1/4n;第2架飞机坠落点就在1/4(n-1)+1/4n……最后倒数第二架飞机坠落点在1/2+……+1/4*(n-1)+1/4n,这个值又要等于3/4;
代码实现就很简单了,最后求得是31架;
总结:这么简单的题都不会写,写题只会套模板,以后多练练思维,最后感谢姐夫,orz;