前言:内容包括:题目,代码实现,大致思路,代码解读
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [1,2,3,1], k = 3
输出:true
示例 2:
输入:nums = [1,0,1,1], k = 1
输出:true
示例 3:
输入:nums = [1,2,3,1,2,3], k = 2
输出:false
typedef struct S
{
int val;
int index;
}S;
int cmp(const void* e1, const void* e2)
{
return ((S*)e1)->val - ((S*)e2)->val;
}
int containsNearbyDuplicate(int* nums, int numsSize, int k)
{
S s[numsSize];
int i = 0;
for (i = 0; i < numsSize; i++)
{
s[i].val = nums[i];
s[i].index = i;
}
qsort(s, numsSize, sizeof(S), cmp);
for (i = 0; i < numsSize-1; i++)
{
if (s[i].val == s[i + 1].val && abs(s[i].index - s[i + 1].index) <= k)
{
return true;
}
}
return false;
}
1 将数组中的每个数字及其下标作为一个整体,需要设计为结构体类型
2 按照数值的大小,从小到大排序所有的结构体数据
3 两两比较排序后的结构体数据,若是前一个和后一个结构体中的数值相同,且这两个结构体中的下标满足: abs(i - j) <= k,则存在重复数字,返回true
当循环结束后仍未提前返回,则不存在重复数字,返回false
typedef struct S
{
int val;
int index;
}S;
找重复数字比较方便的方法是先排序,使得重复的数字聚在一起
但是我们又需要同时保留每个数字的下标,但是仅排序数字的话,排序后数字的下标就会发生改变
所以我们将每个数字和它原先在数组中的下标绑定在一起,形成一个结构体,然后再参与排序
S s[numsSize];
int i = 0;
for (i = 0; i < numsSize; i++)//将每个数字及其下标存入一个结构体类型中
{
s[i].val = nums[i];
s[i].index = i;
}
qsort(s, numsSize, sizeof(S), cmp);
调用库函数qsort排序数据,比较的函数需要我们自己设计
int cmp(const void* e1, const void* e2)
{
return ((S*)e1)->val - ((S*)e2)->val;
}
qsort函数(我的另一篇博客有详解)
for (i = 0; i < numsSize-1; i++)
{
if (s[i].val == s[i + 1].val && abs(s[i].index - s[i + 1].index) <= k)
{
return true;
}
}
return false;
两两比较排序后的结构体数据
注意:i < numsSize-1,不能是i 因为i只需要循环到倒数第二个元素的下标就行,这是最后一次两两比较 若是i