1. 问题
You are given a read only array of n integers from 1 to n.
Each integer appears exactly once except A which appears twice and B
which is missing.Return A and B.
Note: Your algorithm should have a linear runtime complexity. Could
you implement it without using extra memory?Note that in your output A should precede B.
Example:
Input:[3 1 2 5 3]
Output:[3, 4]
A = 3, B = 4
给定一个数组,数组大小为n, 且该数组中存储的数据为1到n. 除了有一个重复的数字,和一个遗失的之外,每个其他数字仅仅出现一次。编写程序实现该算法。
2. 思路
可以用2个数组,大小为数组的长度,分别存储的是重复值的位置标志和遗失的值的位置索引。
public class Solution {
// DO NOT MODIFY THE LIST
public ArrayList<Integer> repeatedNumber(final List<Integer> a) {
boolean repeat[] = new boolean[a.size()];
boolean missing[] = new boolean[a.size()];
ArrayList<Integer> result = new ArrayList<>();
int repeatNum = 0;
for (int val : a) {
if (repeat[val - 1] == false)
repeat[val - 1] = true;
else
repeatNum = val;
}
int missingNum = 0;
for (int val : a) {
missing[val - 1] = true;
}
for (int i = 0; i < a.size(); i++) {
if (!missing[i])
missingNum = i + 1;
}
result.add(repeatNum);
result.add(missingNum);
return result;
}
}
3. 参考答案–另一种解法
参考答案解法:简单粗暴。首先将数组排序;然后找到重复的数字,只需便利一层循环即可得到;遗失的数字仅需通过等差数列求和公式,简单相减即可得到。
public class Solution {
// DO NOT MODIFY THE LIST
public ArrayList<Integer> repeatedNumber(final List<Integer> A) {
ArrayList<Integer> res = new ArrayList<>();
Collections.sort(A);
int n = A.size();
int rep = -1;
int miss = -1;
long sum = A.get(0);
for (int i = 1; i < n; i++) {
if (A.get(i).intValue() == A.get(i - 1).intValue()) {
rep = A.get(i);
}
sum += A.get(i);
}
miss = (int) ((1L * n * (1L * n + 1)) / 2 - sum + rep);
res.add(rep);
res.add(miss);
return res;
}
}