leetcode:存在重复元素Ⅱ(详解)

前言:内容包括:题目,代码实现,大致思路,代码解读

题目:

给你一个整数数组 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

代码解读:

part 1

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;
	}

part 2

qsort(s, numsSize, sizeof(S), cmp);

调用库函数qsort排序数据,比较的函数需要我们自己设计

int cmp(const void* e1, const void* e2)
{
	return ((S*)e1)->val - ((S*)e2)->val;
}

qsort函数(我的另一篇博客有详解)

part 3

    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

你可能感兴趣的:(leetcode,leetcode)