645. Set Mismatch
类似解法问题(index符号标记法)
442. Find All Duplicates in an Array
448. Find All Numbers Disappeared in an Array
问题:
给定size=n的数组,记录1~n。
其中存在某个数字重复,占用另一个数字的空间,导致漏掉那个数字。
返回{重复的数字,漏掉的数字}。
Example 1: Input: nums = [1,2,2,4] Output: [2,3] Example 2: Input: nums = [1,1] Output: [1,2] Constraints: 2 <= nums.length <= 104 1 <= nums[i] <= 104
解法:索引index映射,符号标记法
抓住该题目给定数组的特性:
- 所有元素 在1~n之间,可联系到 数值 和 偏移位置(索引index) 的对应关系。
- 仅出现2次或1次,可联系到正负数的特性。负负得正,一负为负。
那么,可得以下解法:
遍历一次数组,读到一个数值,把其作为index,去标记index对应的值。标记方法为 取反
每次标记前,先判断当前index数值
- 负数:一负得负,一定已经被标记过1次:所求重复数(不再标记)
- 正数:那么可标记(还未访问过)
再一次遍历数组,
还是正数的index,即为还未访问过的。所求漏掉的数。
追加该数值到结果。
代码参考:
1 class Solution { 2 public: 3 vector<int> findErrorNums(vector<int>& nums) { 4 int n = nums.size(); 5 vector<int> res; 6 for(int i=0; i<n; i++) { 7 int idx = abs(nums[i])-1; 8 if(nums[idx]<0) { 9 res.push_back(idx+1); 10 } else { 11 nums[idx] = -nums[idx]; 12 } 13 } 14 for(int i=0; i<n; i++) { 15 if(nums[i]>0) res.push_back(i+1); 16 } 17 return res; 18 } 19 };