LeetCode 26 删除有序数组中的重复项
题目:
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
解题思路:
简单难度的题目,因为已经排列好了,只需要比较当前元素和前一个(或者后一个元素)是否相等就可以判断是否有重复了。合理运用erase(),这里其实有个坑,erase(it)之后会自动让it++,因此不能每次循环都it++;
代码如下:
class Solution {
public:
int removeDuplicates(vector<int>& nums)
{
vector<int>::iterator it;
for(it=nums.begin();it!=nums.end();)
{
if(it==nums.begin())
{
it++;
}
else
{
if(*it==*(it-1))
{
nums.erase(it);
}
else
{
it++;
}
}
}
return nums.size();
}
};
LeetCode 220 存在重复元素III
题目:
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。
如果存在则返回 true,不存在返回 false。
解题思路:
我们利用有序数组加滑动窗口来解决问题:
根据题意,要求再x-k到x+k区间找到一个数位于nums[x]-t到nums[x]+t区间;
利用set对加入的数进行排序,直接用stl自带的lower_bound(二分查找法)对要找的元素进行查找;
STL永远滴神,笔者做题时,手写的二分查找,查看了官方答案才想起来STL有自带的,不用手写,泪目了,将官方简洁代码放上:
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int n = nums.size();
set<int> rec;
for (int i = 0; i < n; i++) {
auto iter = rec.lower_bound(max(nums[i], INT_MIN + t) - t);
if (iter != rec.end() && *iter <= min(nums[i], INT_MAX - t) + t) {
return true;
}
rec.insert(nums[i]);
if (i >= k) {
rec.erase(nums[i - k]);
}
}
return false;
}
};