1.题目
The set S
originally contains numbers from 1 to n
. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.
Given an array nums
representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.
Example 1:
Input: nums = [1,2,2,4] Output: [2,3]
Note:
- The given array size will in the range [2, 10000].
- The given array's numbers won't have any order.
2.思路
用一个集合记录出现过的数字,第二次出现的数字就作为返回序列中的 第一个值;
未出现过数字的寻找方法:原本总和应该是1~n,现在的总和是,丢失了一个数字,重复了一个数字。
因此有 现在的和-重复数字=原本的和-丢失的数字;(都等于正常出现的数字的和)
所以 丢失的数字=原本和-现在和+重复数字。就代替了再在集合set中寻找一次,提高一些效率。
3.算法
class Solution {
public int[] findErrorNums(int[] nums) {
int len=nums.length;//数组的长度
HashSet set=new HashSet();
int[] res=new int[2];
long now=0;
long expected=0;
for(int i=0;i<len;i++){
if(!set.contains(nums[i]))
set.add(nums[i]);
else
res[0]=nums[i];
now+=nums[i];
}
//这个算法就是在set中找丢失的数字,效率较低
// for(int i=1;i<=len;i++){
// if(!set.contains(i)){
// res[1]=i;
// }
// }
for(int i=1;i<=len;i++){
expected+=i;
}
//expected=len*(len+1)/2;//求和算法,竟然比遍历求和耗时更长。乘法估计还是比加法耗时很多。
res[1]=(int)(expected-now+res[0]);
return res;
}
}
4.总结
就是灵活一点,寻找第二个数。要充分利用已有的结果,不必所有都从头去找。