题目:给定一个整数数组,从数组中移除所有值等于val的元素,返回移除元素后数组的长度
第一种解法(暴力解法):
思路:遍历数组中的每个位置的元素,检查是否等于val,
1)若等于val,则将当前位置以后的元素均前移一个位置,并继续从当前位置遍历
2)若不等于val,则遍历下一个位置
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int deleteNum(vector<int>& arr, int key) {
int count = 0;
int arrLen = arr.size(); // 有效数组的长度
for(int i = 0; i < arrLen;) {
if(arr[i] == key) {
count++;
if(i == (arrLen - 1)) { // 当遍历到有效数组尾部时,无需移动元素
break;
}
else {
for(int j = i; j < (arrLen - 1); j++) { // 当尚未遍历到有效数组尾部时,需把当前元素以后的所有元素前移一个位置
arr[j] = arr[j+1];
}
}
arrLen--;
}
else {
i++;
}
}
return count;
}
int main() {
vector<int> arr;
string line;
string temp;
while (getline(cin, line)) {
int i;
for (i = 0; i < line.size(); i++) {
if(line[i] == '[') {
continue;
}
if(line[i] == ',') {
arr.emplace_back(stoi(temp));
temp.clear();
continue;
}
if(line[i] == ']') {
arr.emplace_back(stoi(temp));
temp.clear();
break;
}
temp += line[i];
}
int key = stoi(line.substr(i + 2));
int len = arr.size() - deleteNum(arr, key);
cout << len << endl;
for(int i = 0; i < len; i++) {
cout << arr[i];
if(i != (len - 1)) {
cout << " ";
}
else {
cout << endl;
}
}
arr.clear();
}
return 0;
}
此算法的时间复杂度:O(n^2)
此算法的空间复杂度:O(1)
第二种解法(快慢指针法):
思路:使用快指针遍历数组的每个位置,检查该位置的元素是否等于val,若不等于,则将慢指针后移一个位置,将快指针指向的元素复制到满指针指向的位置。(总的来说,就是用快指针遍历所有元素,用满指针存储需要记录的元素),相比于第一种算法,仅更新了deleteNum函数,代码如下所示
int deleteNum(vector<int>& arr, int key) {
int slowIndex = -1;
for(int fastIndex = 0; fastIndex < arr.size(); fastIndex++) {
if(arr[fastIndex] != key) {
slowIndex++;
arr[slowIndex] = arr[fastIndex];
}
}
return slowIndex + 1;
}
此算法的时间复杂度:O(n)
此算法的空间复杂度:O(1)