|
| 1 | +/* |
| 2 | + * @Author: Chacha |
| 3 | + * @Date: 2022-03-15 15:30:56 |
| 4 | + * @Last Modified by: Chacha |
| 5 | + * @Last Modified time: 2022-03-15 21:37:20 |
| 6 | + */ |
| 7 | + |
| 8 | +/** |
| 9 | + * 来源:https://leetcode-cn.com/problems/remove-element/ |
| 10 | + * |
| 11 | + * 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 |
| 12 | + * 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 |
| 13 | + * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 |
| 14 | + * |
| 15 | + * 示例 1: |
| 16 | + * 输入:nums = [3,2,2,3], val = 3 |
| 17 | + * 输出:2, nums = [2,2] |
| 18 | + * 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。 |
| 19 | + * 例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。 |
| 20 | + * |
| 21 | + * 示例 2: |
| 22 | + * 输入:nums = [0,1,2,2,3,0,4,2], val = 2 |
| 23 | + * 输出:5, nums = [0,1,4,0,3] |
| 24 | + * 解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 |
| 25 | + * 注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。 |
| 26 | + * |
| 27 | + */ |
| 28 | + |
| 29 | +#include <iostream> |
| 30 | +#include <vector> |
| 31 | + |
| 32 | +using namespace std; |
| 33 | + |
| 34 | +class Solution |
| 35 | +{ |
| 36 | +public: |
| 37 | + int removeElement1(vector<int> &nums, int val); |
| 38 | + |
| 39 | + int removeElement2(vector<int> &nums, int val); |
| 40 | +}; |
| 41 | + |
| 42 | +/** |
| 43 | + * 方法一:暴力解法 |
| 44 | + * 暴力的解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。 |
| 45 | + * |
| 46 | + * 时间复杂度:O(n^2) |
| 47 | + * 空间复杂度:O(1) |
| 48 | + * |
| 49 | + */ |
| 50 | +int Solution::removeElement1(vector<int> &nums, int val) |
| 51 | +{ |
| 52 | + int size = nums.size(); |
| 53 | + |
| 54 | + for (int i = 0; i < size; i++) |
| 55 | + { |
| 56 | + |
| 57 | + if (nums[i] == val) |
| 58 | + { |
| 59 | + // 发现需要移除的元素,就将数组集体向前移动一位 |
| 60 | + for (int j = i + 1; j < size; j++) |
| 61 | + { |
| 62 | + nums[j - 1] = nums[j]; |
| 63 | + } |
| 64 | + i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位 |
| 65 | + size--; // 此时数组的大小-1 |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + return size; |
| 70 | +} |
| 71 | + |
| 72 | +/** |
| 73 | + * 方法二:双指针法 |
| 74 | + * 双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。 |
| 75 | + * 时间复杂度:O(n) |
| 76 | + * 空间复杂度:O(1) |
| 77 | + * |
| 78 | + */ |
| 79 | +int Solution::removeElement2(vector<int> &nums, int val) |
| 80 | +{ |
| 81 | + int i = 0; |
| 82 | + |
| 83 | + for (int j = 0; j < nums.size(); j++) |
| 84 | + { |
| 85 | + if (nums[j] != val) |
| 86 | + { |
| 87 | + nums[i++] = nums[j]; |
| 88 | + } |
| 89 | + } |
| 90 | + return i; |
| 91 | +} |
| 92 | + |
| 93 | +void printVector(vector<int> &vec) |
| 94 | +{ |
| 95 | + for (int i = 0; i < vec.size(); i++) |
| 96 | + { |
| 97 | + printf("%3d", vec[i]); |
| 98 | + } |
| 99 | + cout << endl; |
| 100 | +} |
| 101 | + |
| 102 | +int main(int argc, char const *argv[]) |
| 103 | +{ |
| 104 | + Solution s; |
| 105 | + int arr[] = {0, 1, 2, 2, 3, 0, 4, 2}; |
| 106 | + vector<int> nums(arr, arr + sizeof(arr) / sizeof(int)); |
| 107 | + |
| 108 | + cout << "Remove element 2, result is " << s.removeElement1(nums, 2) << endl; // Remove element 2, result is 5 |
| 109 | + |
| 110 | + printVector(nums); |
| 111 | + |
| 112 | + cout << "Remove element 3, result is " << s.removeElement2(nums, 3) << endl; // Remove element 3, result is 7 |
| 113 | + |
| 114 | + printVector(nums); |
| 115 | + |
| 116 | + return 0; |
| 117 | +} |
0 commit comments