Contains Duplicate II Contains Duplicate III
一、
Contains Duplicate II
Given an array of integers and an integer k, find out whether there there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between iand j is at most k.
题意是给定一个数组,问是否存在数组的两个下标i和j,使得nums[i]=nums[j],并且i和j的距离最大为k。
思路:一开始感觉用二重循环,外层循环遍历数组,内层循环对每个外层循环的元素进行考量,看看是否满足要求。此时,时间复杂度是O(n^2),提交后超时。然后想到另一种办法:自定义一个结构体,包含nums的元素值和对应的在数组中的下标:
struct elem
{
long num;
int index;
};
然后以此为基础构建新的数组,对其进行排序,然后再遍历比较。此时时间复杂度为O(nlogn)
struct elem
{
long num;
int index;
};
static bool mypare(struct elem e1, struct elem e2)
{
return e1.num >= e2.num;
}
bool containsNearbyDuplicate(vector<int>& nums, int k)
{
vector<struct elem> v;
for (int i = 0; i < nums.size(); i++)//根据nums元素构建新的数组
{
struct elem e;
e.num = nums[i];
e.index = i;
v.push_back(e);
}
sort(v.begin(), v.end(), mypare);//排序
for (int i = 1; i < v.size(); i++)
{
if (v[i].num == v[i - 1].num && abs(v[i].index - v[i - 1].index) <= k)
return true;
}
return false;
}
二、Contains Duplicate III
此题和上题不同之处在于:nums[i]和nums[j]不在需要相等,只要相差为t即可。基本的方法和上题类似,但是有几点需要注意:
1、nums[i]和nums[j]相差t,如果nums[i]=-1,nums[j]=“int所能表示的最大正数”,则其“相差”就溢出了。因此结构体元素要用long long类型
class Solution {
public:
struct elem
{
long long num;
int index;
};
static bool mypare(struct elem e1, struct elem e2)
{
return e1.num >= e2.num;
}
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t)
{
if (nums.size() == 0)
return false;
vector<struct elem> v;
for (int i = 0; i < nums.size(); i++)
{
struct elem e;
e.num = nums[i];
e.index = i;
v.push_back(e);
}
sort(v.begin(), v.end(), mypare);
for (int i = 0; i < v.size() - 1; i++)
{
for (int j = i + 1; j<v.size() && (long long)abs(v[i].num - v[j].num) <= t; j++)
{
if (abs(v[i].index - v[j].index) <= k)
return true;
}
}
return false;
}
};
三、后记
时间复杂度和空间复杂度都不够理想,希望能有更好的办法。