给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。
示例 1:
输入:nums = [1,2,3,1]
输出:true
示例 2:
输入:nums = [1,2,3,4]
输出:false
示例 3:
输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true
提示:
1 <= nums.length <= 105
-109 <= nums[i] <= 109
思路:
最简单的想法就是对数组进行直接比较,用每一个元素和其它的元素进行比较,如果有相等,就返回true,没有则返回false
直接循环代码如下:
bool containsDuplicate(int* nums, int numsSize){
for (int i = 0; i < numsSize; i++) {
for (int j = i + 1; j < numsSize; j++) {
if (nums[i] == nums[j]) {
return true;
}
}
}
return false;
}
但这样要进行双重循环,时间复杂度为O(n²),效率低,会超时。
这时想到可以先排序,这样排序后相同元素相邻,我们只需要比较相邻元素是否相同即可,可以少一重循环,但排序本身也可能进行循环,所以必须要使用一个简单的排序算法。
如果用Java本身的排序,可以简单求解:
class Solution {
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for(int i=1;i<=nums.length;i++){
if (nums[i] == nums[i - 1]){
return true;
}
}
return false;
}
}
而C语言时间复杂度比较低的排序算法是快排或者使用库函数。
使用快排代码如下:
void quickSort(int*nums, int begin, int end) {
if (begin < end) {
int key = nums[begin];
int i = begin;
int j = end;
while (i < j) {
while (i < j && nums[j] > key) {
j--;
}
if (i < j) {
nums[i] = nums[j];
i++;
}
while (i < j && nums[i] < key) {
i++;
}
if (i < j) {
nums[j] = nums[i];
j--;
}
}
nums[i] = key;
quickSort(nums, begin, i - 1);
quickSort(nums, i + 1, end);
}
}
bool containsDuplicate(int* nums, int numsSize){
if(numsSize==0) return false;
int i=0;
quickSort(nums,0,numsSize-1);
while(i<numsSize-1){
if(nums[i]==nums[++i]) return true;
}
return false;
}
但是有一个测试用例是有序表,是快排中的最坏情况,快排退化为冒泡,直接超时。
这个时候我们可以对快排再进行优化,代码如下:
int sort (int* nums,int begin,int end){
int mid = nums[(begin+end)/2];
nums[(begin+end)/2] = nums[begin];
nums[begin] = mid;
while(begin<end){
while(begin<end&&nums[end]>=mid) --end;
nums[begin] = nums[end];
while(begin<end&&nums[begin]<=mid) ++begin;
nums[end] = nums[begin];
}
nums[begin]=mid;
return begin;
}
void quickSort(int* nums,int begin,int end){
if(begin<end){
int result = sort(nums,begin,end);
quickSort(nums,begin,result-1);
quickSort(nums,result+1,end);
}
}
bool containsDuplicate(int* nums, int numsSize){
if(numsSize==0) return false;
int i=0;
quickSort(nums,0,numsSize-1);
while(i<numsSize-1){
if(nums[i]==nums[++i]) return true;
}
return false;
}
使用库函数qsort排序:
int cmp(int *x, int *y) {
return *x - *y;
}
bool containsDuplicate(int* nums, int numsSize) {
qsort(nums, numsSize, sizeof(int), cmp);
for (int i = 0; i < numsSize - 1; i++) {
if (nums[i] == nums[i + 1]) {
return true;
}
}
return false;
}