小米笔试_2012_09_17

前面的水题直接飘过,进入算法题部分。

算法题一:

有一个数组a,a中有n个数,现在有一个数组b用做结果数组,在数组a中,对于每一个元素a[i],求出了a数组中除了该元素以外其他元素的乘积,并且置于b数组中返回。一道很水的题目,用乘积之和除以每一个元素就可以了,竟然没考虑0,实在不应该。以后每做除法必须要考虑被除数为零的情况。

其实这道题在网上是有原题的,原题的条件比较苛刻,不允许用除法,而且必须用O(n)的时间复杂度和O(1)的空间复杂度。地址如下:http://blog.csdn.net/huagong_adu/article/details/7457948

这里我自己写了一遍供大家参考:

#include<iostream>
using namespace std;

int* getTheProduct(int numbers[],int n)
{
	if(numbers==NULL || n<=0)
		return NULL;

	int* result = new int[n];
	result[n-1]=1;

	for(int i=n-1;i>0;i--)
		result[i-1] = numbers[i]*result[i];

	for(int i=0;i<n-1;i++)
	{
		result[i] *= result[n-1];
		result[n-1] *= numbers[i];
	}

	return result;
}


int main()
{
	//just for testing 
	int numbers[] = {2,6,8,10,12};
	int* result = getTheProduct(numbers,5);
	for(int i=0;i<5;i++)
		cout<<result[i]<<endl;
	delete[] result;
}


算法题二:

设有一个数组numbers,其中有n个元素,n个元素中有三个称为奇异数的元素出现切仅出现了一次,其他元素都出现且仅出现两次,设计一个算法,找出这三个奇异数中的一个,比如说输入数组是numbers{1,2,3,4,5,6,7,6,5,2,1},输出3,4,7中的任意一个数字。

算法思想:算法主干是模仿快速排序,找到一个pivot,将小于等于pivot的数字都置于pivot前面,大于pivot的数字都置于pivot后面,这样数字被为两个部分,pivot归于左边,肯定有一个部分有奇数个数字,有一部分有偶数个数字,奇数个数字的那一部分里面至少有一个数字是只出现一次的,那么应用这个方法继续在那一部分数字上划分,直到最后只有一个数字,这个数字就是只出现一次的那个数字。

这个算法的时间复杂度是O(n),空间复杂度是O(1),在各个算法里面应该算是比较好的算法。

还有一种基于异或的牛逼的办法,考试的时候没想出来,http://blog.csdn.net/orzlzro/article/details/6394412

自己写了一个好像还有点问题,留作以后再检查吧

#include<iostream>
using namespace std;

int getTheNumber(int numbers[],int left,int right)
{
	int index = left;
	int preIndex = left-1;

	while(index < right-1)
	{
		if(numbers[index] <= numbers[right])
		{
			preIndex++;
			int temp = numbers[index];
			numbers[index] = numbers[preIndex];
			numbers[preIndex] = temp;
		}
		index++;
	}

	preIndex++;
	int temp = numbers[preIndex];
	numbers[preIndex] = numbers[right];
	numbers[right] = temp;

	int flag = preIndex-left+1;

	if(flag==1)
		return numbers[preIndex];
	else if(flag%2==1)
		return getTheNumber(numbers,left,preIndex);
	else
		return getTheNumber(numbers,preIndex+1,right);
}


int main()
{
	//just for testing 
	int numbers[] = {2,7,6,6,8,9,10,12,9,2,7};
	int result = getTheNumber(numbers,0,10);
	cout<<result<<endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值