写在前面的话
判断是否存在重复值,大致两种思路,一种是加以优化的双重for法,对每一个数进行每一对的比对,超级耗时勉强通过检验; 再就是对元素进行快速排序,再进行是否重复的判断。
题目内容
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
1. 解法1
1.1 解题思路
设定I,J标志,对每一个nums[i],从自身向后在数组中进行一次遍历,查看是否有重复。
1.2 C实现
bool containsDuplicate(int* nums, int numsSize) {
bool flag = false;
if(numsSize==0||numsSize==1)
return false;
for(int i=0;i<numsSize-1;i++){
for(int j=i+1;j<numsSize;j++){
if (nums[i] == nums[j]){
flag = true;
break;
}
}
}
return flag;
}
1.3 时间复杂度分析
尽管进行过优化,满足条件后break,以及j=i的循环,根据时间复杂度乘法规则,时间复杂度是O(n²),具体27个例子执行时间在1800ms左右。
2. 解法2
2.1 解题思路
对该数组进行快速排序,再遍历一次数组,对nums[i]与nums[i+1]进行比对,查看是否有重复。
2.2 C实现
bool containsDuplicate(int* nums, int numsSize) {
bool flag = false;
sort(nums,0,numsSize-1);
for(int i=0;i<numsSize-1;i++){
if(nums[i] == nums[i+1]){
flag = true;
break;
}
}
return flag;
}
void sort(int *a, int left, int right)
{
if(left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
{
return ;
}
int i = left;
int j = right;
int key = a[left];
while(i < j) /*控制在当组内寻找一遍*/
{
while(i < j && key <= a[j])
{
j--;
}
a[i] = a[j];
while(i < j && key >= a[i])
{
i++;
}
a[j] = a[i];
}
a[i] = key;
sort(a, left, i - 1);
sort(a, i + 1, right);
}
2.3 时间复杂度分析
根据时间复杂度加法规则,复杂度为快速排序的时间复杂度,O(nLog n)。具体27个例子执行时间为1400ms。
结语
本问题还有更巧妙地解法,等待日后探究。