请设计一个高效算法,判断数组中是否有重复值。必须保证额外空间复杂度为O(1)。
给定一个int数组A及它的大小n,请返回它是否有重复值。
测试样例:
[1,2,3,4,5,5,6],7
返回:true
这道题目要求高效,并且要求空间复杂度为O(1).这样就不能用哈希表是实现,只能先排序再遍历实现
经典排序算法空间复杂度如下:
O(1)
冒泡排序,选择排序,插入排序,希尔排序,堆排序
O(logN)~O(N)
快速排序
O(N)
归并排序
O(M)
计数排序和基数排序
所以选择堆排序,并且不能使用递归时间,因为递归函数要如栈,需要额外的空间开销。利用大根堆,循环实现排序代码如下
class Checker {
public:
bool checkDuplicate(vector<int> a, int n) {
if(n<2)
return false;
do
{
buildheap(a,n);
swapnum(a[0],a[n-1]);
}while(n--);
for(int i=0;i!=a.size()-1;++i)
{
if(a[i]==a[i+1])
return true;
}
return false;
// write code here
}
void buildheap(vector<int> &a,int lena)
{
if(lena<2)
return;
if(a[(lena-2)/2]<a[lena-1])
swapnum(a[(lena-2)/2],a[lena-1]);
if(lena%2==1)
{
if(a[(lena-2)/2]<a[lena-2])
swapnum(a[(lena-2)/2],a[lena-2]);
}
for(int i=(lena-4)/2;i>=0;--i)
{
if(a[i]<a[2*i+1])
swapnum(a[i],a[2*i+1]);
if(a[i]<a[2*i+2])
swapnum(a[i],a[2*i+2]);
}
}
void swapnum(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
};