-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNArray.java
More file actions
85 lines (70 loc) · 2.39 KB
/
Copy pathNArray.java
File metadata and controls
85 lines (70 loc) · 2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* 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.
Sum(Actual) = Sum(1...N) + A - B
Sum(Actual) - Sum(1...N) = A - B.
Sum(Actual Squares) = Sum(1^2 ... N^2) + A^2 - B^2
Sum(Actual Squares) - Sum(1^2 ... N^2) = (A - B)(A + B)
= (Sum(Actual) - Sum(1...N)) ( A + B).
// sum = A - B
// squareSum = A^2 - B^2 = (A - B)(A + B)
// squareSum / sum = A + B
*/
import java.util.*;
public class NArray{
public static ArrayList<Integer> repeatedNumber(final List<Integer> A) {
ArrayList<Integer> result = new ArrayList<Integer>();
int[] count = new int[A.size() + 1];
for(int i = 0; i < A.size(); i++){
count[A.get(i)]++;
}
for(int i = 1; i < count.length; i++){
if(count[i] > 1)
result.add(i);
}
for(int i = 1; i < count.length; i++){
if(count[i] == 0)
result.add(i);
}
return result;
}
//Efficient approach
public static ArrayList<Integer> repeatedNumberEfficient(final List<Integer> A) {
ArrayList<Integer> result = new ArrayList<Integer>();
long sum = 0;
long squareSum = 0;
long temp;
for(int i = 0; i < A.size(); i++){
temp = A.get(i);
sum = sum + temp;
sum = sum - (i + 1);// this will give us A - B at end.
squareSum = squareSum + temp * temp;
squareSum = squareSum - (i+1)*(i+1); // this will give us A^2 - B^2
}
squareSum = squareSum / sum; //(A-B)(A+B)/(A-B) = (A+B)
int X = (int)(squareSum + sum) / 2;
int Y = (int)squareSum - X;
result.add(X);
result.add(Y);
return result;
}
public static void main(String[] args){
ArrayList<Integer> A = new ArrayList<Integer>();
A.add(3);
A.add(1);
A.add(2);
A.add(5);
A.add(3);
ArrayList<Integer> result = repeatedNumberEfficient(A);
for(int i = 0; i < result.size(); i++)
System.out.print(result.get(i) + " ");
}
}