链表等复杂数据结构用多了,简单的数组操作也不能遗忘!
1. 给定一个有序数组,移除所有重复元素并返回新的数组长度,不能分配额外数组的内存空间。
e.g. 给定输入的数组 = [1,1,2],函数应当返回新长度 = 2,前 2 个元素为 1 和 2。超出新长度所剩下什么元素都无所谓,即新数组可以 = [1,2,2]。
一开始没读懂 “It doesn't matter what you leave beyond the new length.” 的含义,用了 erase 方法非常复杂,答案比较简略。
1 int removeDuplicates(vector<int>& nums) { 2 int count = 0; 3 for (int i = 1; i < nums.size(); i++) { 4 if (nums[i] == nums[i - 1]) 5 count++; 6 else 7 nums[i - count] = nums[i]; 8 } 9 return nums.size() - count; 10 }
这个更加易懂
1 int removeDuplicates(vector<int>& nums) { 2 if (nums.empty()) return 0; 3 int count = 1; 4 for (int i = 1; i < nums.size(); i++) 5 if (nums[i] != nums[i - 1]) 6 nums[count++] = nums[i];
7 return count; 8 }
但这样的代码不够“好看”,可以改进为
1 int removeDuplicates(vector<int>& nums) { 2 int i = 0; 3 for (int n : nums) 4 if (!i || n != nums[i-1]) 5 nums[i++] = n; 6 return i; 7 }
如果不想用 !i 来做第一个元素的判断,代码还能写的更巧妙
1 int removeDuplicates(vector<int>& nums) { 2 int i = !nums.empty(); 3 for (int n : nums) 4 if (n != nums[i-1]) 5 nums[i++] = n; 6 return i; 7 }
int i = !nums.empty(); 这样的写法真的很有趣很有趣,值得学习!
2. 给定一个数组和一个值,移除数组中所有等于该值的元素,并返回新数组的长度,不能分配额外数组的内存空间。超出新长度所剩余的元素也不考虑。
使用类似的方法很快解决
1 int removeElement(vector<int>& nums, int val) { 2 int i = 0; 3 for(int n : nums) { 4 if (n != val) 5 nums[i++] = n; 6 } 7 return i; 8 }