前面的水题直接飘过,进入算法题部分。
算法题一:
有一个数组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;
}