首试公司面试算法题

博客探讨了在面试中遇到的算法题,包括有序数列中查找value的首次出现位置和无序数列中求第k大数值的解决方案。针对这两个问题,提出了从二分查找、堆排序到优化的快速排序等不同算法,分析了它们的时间和空间复杂度。最后,博主分享了解决飞机加油问题的思考过程,并意识到需要提升自己的思维能力。
摘要由CSDN通过智能技术生成
前几天回家姐夫给我出了三道面试题(新手难度);

题目
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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值