解法1:
时间复杂度 O(n ^2)
空间复杂度 O(1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
// # 定义一个特殊值和 长度值
// # 一步步遍历, 如果找到特殊值 则跳过
// # 否则 将新值 插入到 长度值位置 长度值+1
//
if (nums.size() == 0) {
return 0;
}
if (nums.size() == 1) {
return 1;
}
int special =nums[0], length = 1;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] != special){
// cout << i << endl;
// for (auto i : nums){
// cout << i << " " ;
// }
cout << endl;
nums[length] = nums[i];
length ++;
for (int j = length; j < nums.size(); j++){
if(nums[j] == nums[length - 1]) {
nums[j] = special;
}
}
}
}
// for (auto i : nums){
// cout << i << endl;
// }
return length;
}
};
题解2 :
时间复杂度 O(n )
空间复杂度 O(1)
审题中发现是已经排好序的数组 , 那么就简单了, 因为重复的元素是相邻的;
那么就不需要 第二波的遍历了, 第二波的遍历 只需要更改前面的向量元素即可
所以 用一个双指针的策略
算法思想如下
- 定义两个指针 p q p表示 已经删除后的最后一个数组元素, q 表示 目前遍历后的元素
- 一步步遍历 如果 q 指向的元素 是数组尾 元素 那么就q ++
- 否则 将新值 插入到 p + 1 位置
代码如下
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
// 定义两个指针 p q p表示 已经删除后的最后一个数组元素, q 表示 目前遍历后的元素
// 一步步遍历 如果 q 指向的元素 是数组尾 元素 那么就q ++
// 否则 将新值 插入到 p + 1 位置
int p = 0, q = 1, len = nums.size() ;
//异常处理
if(len== 0 || len == 1) {
return len;
}
for (int q = 1; q < len; q++) {
if(nums[p] == nums[q]){
continue;
} else {
p++;
nums[p] = nums[q];
}
}
return p+1;
}
};
心得
- 审题关键
- 双指针问题