您的位置:首页 > 其它

如何判定数组是否存在重复元素

2016-06-27 16:44 387 查看
题目:假设数组 array 有 n 个元素,元素取值范围是 1~n,如何判定数组是否存在重复元素?

方法一:对数组进行排序(可以用效率比较高的排序算法,如快速排序、堆排序等),然后比较相邻的元素是否相同。时间复杂度为 O(nlogn),空间复杂度为O(1)。下面借助c语言类库中自带的快速排序算法qsort,来实现排序。

#include <iostream>

int comp(const void *a, const void *b) // 注意const
{
return *(int *)a - *(int *)b; // 升序
}

bool IsArrayRepeat(int *arr, int len)
{
if (!arr || len <= 1)
return false;

qsort(arr, len, sizeof(int), comp);

for (int i = 0; i < len - 1; i++)
{
if (arr[i] == arr[i + 1])
return true;
}

return false;
}

int main(int argc, const char * argv[]) {

int arr[7] = {1,2,3,4,5,6,2};
int len = sizeof(arr)/sizeof(int);

if (IsArrayRepeat(arr, len))
printf("数组中存在重复元素\n");
else
printf("数组中不存在重复元素\n");

return 0;
}


备注:上述程序的运行环境为:Xcode。

(1)qsort 是 C 标准库函数,包含在头文件 stdlib.h 中。

在 ISO C++中为 std::qsort,包含在文件 cstdlib 中。
#include<cstdlib>
之后,可以直接调用 std::qsort 或 using namespace std;然后再调用 qsort。

(2)sort( )和qsort( )知识点补充: C++ 排序函数 sort(),qsort()的用法

方法二:Hash法 或者 位图法,时间复杂度 和 空间复杂度 都是 O(n)。

方法三:由于本题中数组array有 n 个元素,而且元素的取值范围是 1~ n,所以可以通过遍历数组,假设下标 i 位的数字为 j。那么通过交换,将“下标 i 位上的数字 j“ 交换到“下标 j - 1 位上“,直到所有数字都出现在自己对应的下标处,或发生了冲突。此算法的时间复杂度为O(n),空间复杂度为O(1)。

#include <iostream>

bool IsArrayRepeat2(int arr[], int len)
{
if (!arr || len <= 1)
return false;
for (int i = 0; i < len; i++)
{
if (arr[i] <= 0 || arr[i] > len)
return false;
}

int j = -1;
for (int i = 0; i < len; i++)
{
j = arr[i];
if (i == j - 1)
continue;
if (arr[i] == arr[j - 1])
return true;
arr[i] = arr[j - 1];
arr[j - 1] = j;
i--;
}

return false;
}

int main(int argc, const char * argv[]) {

int arr[7] = {7,1,3,4,7,6,2};
int len = sizeof(arr)/sizeof(int);

if (IsArrayRepeat2(arr, len))
printf("数组中存在重复元素\n");
else
printf("数组中不存在重复元素\n");

return 0;
}


补充一个注意点,关于数组越界的问题(上述代码的运行环境,均为Xcode):

bool IsArrayRepeat2(int arr[], int len) // 主要针对IsArrayRepeat2做一些说明
{
if (!arr || len <= 1)
return false;

// 如果把IsArrayRepeat2中的这段代码注释掉,那么当原arr[7]数组中出现0、-1、8等数字时,虽然会造成arr[j-1]越界,但是程序仍然能正常运行,没有报错。但是输出是错误的,数组越界时访问到的数值会给输出带来异常,所以加上这段代码很有必要。
//    for (int i = 0; i < len; i++)
//    {
//        if (arr[i] <= 0 || arr[i] > len)
//            return false;
//    }

int j = -1;
for (int i = 0; i < len; i++)
{
j = arr[i];
if (i == j - 1)
continue;
if (arr[i] == arr[j - 1])
return true;
arr[i] = arr[j - 1];
arr[j - 1] = j;
i--;
}

return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息