Find what number it used to be before element reset - java

Given an array with any size, in my case the array size is 5.
This array contains ALL numbers from 1 to 5 (must contain all of them)
[1 | 2 | 3 | 4 | 5]
0 1 2 3 4
And now, one element was reset and was set to 0, and the mission is to find what number it used to be before it turned 0.
So I have this simple solution:
Explained: First, loop from 1 to 5, create an inner loop to check if the i from the first loop exists in the whole array, if it doesn't exist, that means that it is the value it used to be before 0, because the array contained all numbers from 1 to 5 or 1 to 100 (doesn't matter) and there's on'y one rested element.
Code:
int[] numbers = new int[]{1, 2, 3, 4, 5};
numbers[1] = 0;
int lost = -1;
loop:
for (int i = 1; i <= numbers.length; i++) {
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] == i) {
continue loop;
}
}
lost = i;
break loop;
}
System.out.println(lost);
That solution is not bad, but I think there's a better solution, something more stable.
I have thought about it mathematically, in our example:
1 + x + 3 + 4 + 5 = 15
x = 2
Mathematically, it's really easy. Is there a way this can be done in a programming language as easy as it is mathematically?
Any better algorithms you can think of to solve this question?

This works for ONE element being reset. Just subtract each remaining element from the sum and what ever is left over would have been the previous number the element was before it was reset.
public static void main(String[] args) throws Exception {
int sum = 15;
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
numbers[4] = 0;
for (int i = 0; i < numbers.length; i++) {
sum -= numbers[i];
}
System.out.println(sum);
}
Results:
5

There is one more possibility, you can use HashMaps!
you don't have to traverse through any "for loops" then.
You can use Hashmaps to check whether is there any value for the key of "0", if yes then that is the case where some number is reset to 0.
Then you can traverse the Hashmap and compare which value is missing.
Everything is done With O(1) complexity and worst case of O(n) complexity.

Related

Plus Multiply | December Long Challenge Division 2

The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers A1,A2,…,AN.
Output
For each test case, print a single line containing one integer ― the desired number of pairs.
Example Input
2
3
2 4 2
3
0 2 3
Example Output
1
0
My solution looks like:
class Codechef {
public static void main (String[] args) throws java.lang.Exception {
ArrayList<Integer> resultList = new ArrayList<Integer>();
Scanner scanner = new Scanner(System.in);
int T;
T = scanner.nextInt();
for(int i = 0; i < T; i++) {
int N;
N = scanner.nextInt();
int A[] = new int[N];
for(int j = 0; j < N; j++) {
A[j] = scanner.nextInt();
}
quick_sort(A, 0, N-1);
int pos = 0, pairs = 0;
while(pos < A.length - 1) {
if(A[pos] == A[pos + 1]) {
pos += 2;
pairs += 1;
} else {
++pos;
}
}
resultList.add(pairs);
}
for(int pairCount : resultList) {
System.out.println(pairCount);
}
scanner.close();
}
}
It successfully runs the example test cases but fails on submission, My question is, if the input is something like 1 1 2 2 1, then what should be the answer, 3? as there are 2 pairs of 1, and 1 of 2's.
Also, what will be the suggested data structure to be used for this purpose, Java with primitive data types is taking too much longer to execute it with 40,000 input values. What's wrong with my solution
To answer your first question, I'd say yes that each pair of 1's would count separately so you'd get 3.
I think your code is failing since you're only counting touching pairs after you sort.
For example,
1 1 1, you find the first pair at index 0/1, but then advance pos += 2.This means you're missing the two other pairs of 1's.
Your solution seems to be O(nlogn) because of sorting but I can think of a O(n) solution.
int[] backing = new int [10];
for (int j = 0; j < N; j++) {
int x = scanner.nextInt();
backing[x]++;
}
//At this point, you have a backing array with the frequency of each integer
You'll want something similar to this to calculate the number of pairs. It's the frequency of each integer choose 2, since you want to choose each occurrence of a pair.
So for example if you know you have 5 1's, then you'll compute:
5!/(2!*3!) = 10

Filling an array with a mathematical sequence

I want to write a code that asks for three numbers dig(1), dig(2), dig(3) and displays a sequence of numbers dig(1), dig(2), dig(3), ..., dig(n) according to this rule:
a = dig(2) - dig(1)
b = dig(3) - dig(2)
dig(n) = dig(n-1) + a if n is odd
dig(n) = dig(n-1) + b if n is even
Example:
7, 8, 5, 6, 3, 4, 1, 2, -1, 0
It asks an user for three integers dig1, dig2, dig3
It asks a number N ≥ 3 which will be the whole sequence count.
It prints a sequence beginning with
Then prints the sequence, beginning with the three leading integers, followed by N-3 other terms that follow the pattern defined by the first three integers. See examples below for more information.
(The sequence begins with n = 1, but of course the array starts at 0.)
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int a;
int b;
int n = 0;
int i;
dig1 = scnr.nextInt();
dig2 = scnr.nextInt();
dig3 = scnr.nextInt();
n = scnr.nextInt();
int[] array = new int[n];
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
a = dig2 - dig1;
b = dig3 - dig2;
for (i = 3; i < n; i++){
if(i%2 == 0){
array[i] = b + array[i-1];
}
else{
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
}
}
whenever I try to print this out, I get this error:
java.lang.ArrayIndexOutOfBoundsException
Another example: if I put in the numbers: 0 1 0 9 into my input, I should receive back the sequence 0 1 0 1 0 1 0 1 0
Printing array[n-1] gives me back just the final output. I'm trying to iterate through each number.
Sorry if that's unclear, but any help would be great, thank you.
Your System.out.println(array[i]); seems to be out of the for loop. Then i will be equal to n. And there is no element with index n in array with length n. The elements are from 0 to n-1.
At first I thought that you were choosing an array size less than 3, and that the code was failing here, during the initialization of the array:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
But now, I actually think that the last line of code is the problem. Have a closer look at your for loop:
for (i=3; i < n; i++) {
if (i % 2 == 0) {
array[i] = b + array[i-1];
}
else {
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
Appreciate that at the end of the for loop, i, the loop counter, will always be n, the size of the array. Accessing array[n] will always be out of bounds, because an array in Java has a highest addressable index of one less than the actual number of buckets. So, if you were intending to just print the final element, then use this:
System.out.println(array[i-1]);
or
System.out.println(array[n-1]);
at the line n=scrn.nextInt(), you are assigning to n a integer from scrn but you don't know the value of that integer.
Then with this:
int[] array = new int[n];
Your array is of size of n elements starting from index 0 to index n-1.
So let's suppose the value you affected to n with .nextInt() is inferior to 3: initial value of i, the loop will even not be reached, because you will be out of bounds just here:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
since you will be attempting to affect a value on an array at an index that does not exists (n is inferior to three but you are trying to affect three values in an array of size n).
Then if n is superior to 3, since your printing code is out from the loop, the value of i is equal to n and there is no value at index n. remember, the loop will leave only if the condition i<n is false and to reach that condition i must be equal or superior and that will lead to an IndexOutOfBoundsException on printing.
I think you printing line code should be inside the for loop.

how to add elements in a 2d array

I just want to know how this program works, and why the answer is 14.
here is the code:
public class extra {
public static void main(String[] args){
int[][] table = {{1,2,3},{4,5,6},{7,8,9}};
int sum = 0;
for( int i = 2; i > 0; i-- )
sum += table[i][3-i];
System.out.println(sum);
}
}
I understand the way the matrix is set up
123
456
789
but what is i in this problem, because I thought it was the number of rows, but since it is in a for loop, does it mean that i is the number in the matrix? Also how do the [i][3-i] come in to affect? The answer is 14, and I just want to know how it is 14.
It is only summing part of a diagonal, specifically table[2][1] which is 8, and table[1][2] which is 6.
The easiest way to see what is going on is to add an output statement in the loop:
for (int i = 2; i > 0; i--) {
sum += table[i][3 - i];
System.out.println(i + " " + (3 - i) + " " + table[i][3 - i]);
}
your program takes table[2][1] (value of 8) and table[1][2] (value of 6) elements, sums them and prints as output (value of 14)
regarding your question in a title your main method should be more like this:
public static void main(String[] args) {
int[][] table = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int sum = 0;
System.out.println("Before\n");
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
sum += table[i][j];
System.out.printf("Sum after %d iteration: %d\n", i + j + 1, sum);
}
}
System.out.println("\nIn total: " + sum);
}
i + j + 1 is a sum of current iteration which is sum of both axises, and since Java has 0-based indexed tables, it is increased by 1
Hope it helps!
i, in itself, does not correspond directly to anything in the matrix. It is just the name of the variable that the for loop changes each time it loops.
The [i][3-i] is how the i interacts with table. On the first round of the for loop, the i will be equal to 2. Thus, sum will be increased by table[2][1], which is the 3rd row and the 2nd column of the matrix, which has a value of 8.
On the second round of the for loop, the for loop, the i will be equal to 1. Thus, sum will be increased by table[1][2], which is the 2nd row and the 3rd column of the matrix, which has a value of 6.
Therefore, sum will be equal to 8+6=14.
What the for loop does is as follows:
i = 2. Enter loop.
Add table[2][3-2] to sum. Sum is now 8, because table[2][1] = 8.
Decrement i by 1.
i = 1. Enter loop.
Add table[1][3-1] to sum. Sum is now 14, because table[1][2] = 6.
Decrement i by 1.
i = 0. 0 is not greater than 0, so we exit the loop. The sum became 14.
Two-dimensional arrays like int[][] table have two indexes. One for the "outer" array (or rows), and one for the "inner" ones (columns).
Let's use int[][] table = {{1,2,3},{4,5,6},{7,8,9}}; from your code as an example:
table[1][2]: 1 means we should look in the array at index 1, which is {4,5,6}. 2 means we should look at {4,5,6}'s index 2, which is 6. In other words table[1][2] == 6.
table[2][0]: 2 means we should look in the array at index 2, which is {7,8,9}. 0 means we should look at {7,8,9}'s index 0, which is 7.
for (int i = 2; i > 0; i--)
so starting at 2 it checks if i is greater than zero
loops once then i-- subtracts 1
check again still greater than 0
loops again then subtracts 1 again
checks if greater than 0 now 0 it is not greater than 0 so stops looping
//thus loops 2 times
//[0] = 1st [1] = 2nd [2] = third ...
//counting in code starts at zero not 1 so and array of 3 counts a the spaces 0,1,2
int sum = 0;//sum starts at zero
//using the value of i translates as such
sum += table[2][3-2];//[2][1]this is 3rd group 2nd part so sum += 8
//then
sum += table[1][3-1];//[1][2]this is 2nd group 3rd part so sum += 6
0 + 8 + 6 = 14
Here's how to add elements in a 2D array in a easy way.
First when you initialize a 2D array think of the first brackets [ ] as a column and the second bracket [ ] as column rows.
For example: int[][] num = new int[10][5] which means 10 columns and 5 rows.
If you want to fill all the elements in a 2D array you must use two for loops:
int[][] num = new int[10][5];
for (int i =0; i < num.length;i++ ) {
for (int x=0; x < num[0].length;i++) { //we used num[0] because we need the length of the rows not the columns
num[i][x] = //any value you want to assign
}
}

Histogram project: code throws ArrayIndexOutOfBoundsException

This is the code I've isolated:
public static void randomIntArray(int n) {
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
a[i] = randomInt(-5, 15);
}
scoreHist(a);
}
public static void scoreHist(int[] scores) {
int[] counts = new int[30];
for (int i = 0; i < scores.length; i++) {
int index = scores[i];
counts[index]++;
}
}
But whenever I run this, it gives me this:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: (Insert Random # Here)
at arrayhistogram.ArrayHistogram.scoreHist(ArrayHistogram.java:39)
at arrayhistogram.ArrayHistogram.randomIntArray(ArrayHistogram.java:31)
at arrayhistogram.ArrayHistogram.main(ArrayHistogram.java:21)
I'm lost with this. Ideas? I'm really stuck and have been going in circles with this for a while now.
int index = scores[i];
counts[index]++;
according to the randomInt (-5,15), it's possible the index can be negative.
Change
counts[index]
to
counts[index + 5]
This is because index comes from the a array whose elements are initialized to values between -5 and 14 inclusive. However only values between 0 and 29 inclusive are allowed as indices to counts, hence you need to add 5.
So this is the stuff that your code does :
You pick 'n' random numbers from -5 to 15 ( say n=5 ), push them into an array
Say, the array becomes
scores[] = {0,1,1,5,-3}
Now, you are passing this created array in the scoreHist().
Now, see the state of variables during run time
i scores[i] index counts[index]
--- --------- ----- ----------------------
//1st iteration
0 scores[0]=0 0 counts[0]=counts[0]+1 -> 1
Everything goes fine in the first iteration.
//2nd iteration
1 scores[1]=1 1 counts[1]=counts[1]+1 -> 1
Everything goes fine here as well. Now "counts[] = {1,1}"
//3rd iteration
2 scores[2]=1 1 counts[1]=counts[1]+1 -> 2
Things go alright. counts[1] has been updated. Now "counts[] = {1,2}"
//4th iteration
3 scores[3]=5 5 counts[5]=counts[5]+1 -> 1
Things go absolutely fine here .
//5th iteration
4 scores[4]=-3 -3 counts[-3] !!!!!!!! It is out of bound limits for the
array. This index does not exist.
This is what causes the exception that you have
Hope this helps.

Find duplicate element in array in time O(n)

I have been asked this question in a job interview and I have been wondering about the right answer.
You have an array of numbers from 0 to n-1, one of the numbers is removed, and replaced with a number already in the array which makes a duplicate of that number. How can we detect this duplicate in time O(n)?
For example, an array of 4,1,2,3 would become 4,1,2,2.
The easy solution of time O(n2) is to use a nested loop to look for the duplicate of each element.
This can be done in O(n) time and O(1) space.
(The algorithm only works because the numbers are consecutive integers in a known range):
In a single pass through the vector, compute the sum of all the numbers, and the sum of the squares of all the numbers.
Subtract the sum of all the numbers from N(N-1)/2. Call this A.
Subtract the sum of the squares from N(N-1)(2N-1)/6. Divide this by A. Call the result B.
The number which was removed is (B + A)/2 and the number it was replaced with is (B - A)/2.
Example:
The vector is [0, 1, 1, 2, 3, 5]:
N = 6
Sum of the vector is 0 + 1 + 1 + 2 + 3 + 5 = 12. N(N-1)/2 is 15. A = 3.
Sum of the squares is 0 + 1 + 1 + 4 + 9 + 25 = 40. N(N-1)(2N-1)/6 is 55. B = (55 - 40)/A = 5.
The number which was removed is (5 + 3) / 2 = 4.
The number it was replaced by is (5 - 3) / 2 = 1.
Why it works:
The sum of the original vector [0, ..., N-1] is N(N-1)/2. Suppose the value a was removed and replaced by b. Now the sum of the modified vector will be N(N-1)/2 + b - a. If we subtract the sum of the modified vector from N(N-1)/2 we get a - b. So A = a - b.
Similarly, the sum of the squares of the original vector is N(N-1)(2N-1)/6. The sum of the squares of the modified vector is N(N-1)(2N-1)/6 + b2 - a2. Subtracting the sum of the squares of the modified vector from the original sum gives a2 - b2, which is the same as (a+b)(a-b). So if we divide it by a - b (i.e., A), we get B = a + b.
Now B + A = a + b + a - b = 2a and B - A = a + b - (a - b) = 2b.
We have the original array int A[N]; Create a second array bool B[N] too, of type bool=false. Iterate the first array and set B[A[i]]=true if was false, else bing!
You can do it in O(N) time without any extra space. Here is how the algorithm works :
Iterate through array in the following manner :
For each element encountered, set its corresponding index value to negative.
Eg : if you find a[0] = 2. Got to a[2] and negate the value.
By doing this you flag it to be encountered. Since you know you cannot have negative numbers, you also know that you are the one who negated it.
Check if index corresponding to the value is already flagged negative, if yes you get the duplicated element. Eg : if a[0]=2 , go to a[2] and check if it is negative.
Lets say you have following array :
int a[] = {2,1,2,3,4};
After first element your array will be :
int a[] = {2,1,-2,3,4};
After second element your array will be :
int a[] = {2,-1,-2,3,4};
When you reach third element you go to a[2] and see its already negative. You get the duplicate.
Scan the array 3 times:
XOR together all the array elements -> A. XOR together all the numbers from 0 to N-1 -> B. Now A XOR B = X XOR D, where X is the removed element, and D is the duplicate element.
Choose any non-zero bit in A XOR B. XOR together all the array elements where this bit is set -> A1. XOR together all the numbers from 0 to N-1 where this bit is set -> B1. Now either A1 XOR B1 = X or A1 XOR B1 = D.
Scan the array once more and try to find A1 XOR B1. If it is found, this is the duplicate element. If not, the duplicate element is A XOR B XOR A1 XOR B1.
Use a HashSet to hold all numbers already seen. It operates in (amortized) O(1) time, so the total is O(N).
I suggest using a BitSet. We know N is small enough for array indexing, so the BitSet will be of reasonable size.
For each element of the array, check the bit corresponding to its value. If it is already set, that is the duplicate. If not, set the bit.
#rici is right about the time and space usage: "This can be done in O(n) time and O(1) space."
However, the question can be expanded to broader requirement: it's not necessary that there is only one duplicate number, and numbers might not be consecutive.
OJ puts it this way here:
(note 3 apparently can be narrowed)
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
The question is very well explained and answered here by Keith Schwarz, using Floyd's cycle-finding algorithm:
The main trick we need to use to solve this problem is to notice that because we have an array of n elements ranging from 0 to n - 2, we can think of the array as defining a function f from the set {0, 1, ..., n - 1} onto itself. This function is defined by f(i) = A[i]. Given this setup, a duplicated value corresponds to a pair of indices i != j such that f(i) = f(j). Our challenge, therefore, is to find this pair (i, j). Once we have it, we can easily find the duplicated value by just picking f(i) = A[i].
But how are we to find this repeated value? It turns out that this is a well-studied problem in computer science called cycle detection. The general form of the problem is as follows. We are given a function f. Define the sequence x_i as
x_0 = k (for some k)
x_1 = f(x_0)
x_2 = f(f(x_0))
...
x_{n+1} = f(x_n)
Assuming that f maps from a domain into itself, this function will have one of three forms. First, if the domain is infinite, then the sequence could be infinitely long and nonrepeating. For example, the function f(n) = n + 1 on the integers has this property - no number is ever duplicated. Second, the sequence could be a closed loop, which means that there is some i so that x_0 = x_i. In this case, the sequence cycles through some fixed set of values indefinitely. Finally, the sequence could be "rho-shaped." In this case, the sequence looks something like this:
x_0 -> x_1 -> ... x_k -> x_{k+1} ... -> x_{k+j}
^ |
| |
+-----------------------+
That is, the sequence begins with a chain of elements that enters a cycle, then cycles around indefinitely. We'll denote the first element of the cycle that is reached in the sequence the "entry" of the cycle.
An python implementation can also be found here:
def findDuplicate(self, nums):
# The "tortoise and hare" step. We start at the end of the array and try
# to find an intersection point in the cycle.
slow = 0
fast = 0
# Keep advancing 'slow' by one step and 'fast' by two steps until they
# meet inside the loop.
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast:
break
# Start up another pointer from the end of the array and march it forward
# until it hits the pointer inside the array.
finder = 0
while True:
slow = nums[slow]
finder = nums[finder]
# If the two hit, the intersection index is the duplicate element.
if slow == finder:
return slow
Use hashtable. Including an element in a hashtable is O(1).
One working solution:
asume number are integers
create an array of [0 .. N]
int[] counter = new int[N];
Then iterate read and increment the counter:
if (counter[val] >0) {
// duplicate
} else {
counter[val]++;
}
This can be done in O(n) time and O(1) space.
Without modifying the input array
The idea is similar to finding the starting node of a loop in a linked list.
Maintain two pointers: fast and slow
slow = a[0]
fast = a[a[0]]
loop till slow != fast
Once we find the loop (slow == fast)
Reset slow back to zero
slow = 0
find the starting node
while(slow != fast){
slow = a[slow];
fast = a[fast];
}
slow is your duplicate number.
Here's a Java implementation:
class Solution {
public int findDuplicate(int[] nums) {
if(nums.length <= 1) return -1;
int slow = nums[0], fast = nums[nums[0]]; //slow = head.next, fast = head.next.next
while(slow != fast){ //check for loop
slow = nums[slow];
fast = nums[nums[fast]];
}
if(slow != fast) return -1;
slow = 0; //reset one pointer
while(slow != fast){ //find starting point of loop
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
}
This is an alternative solution in O(n) time and O(1) space. It is similar to rici's. I find it a bit easier to understand but, in practice, it will overflow faster.
Let X be the missing number and R be the repeated number.
We can assume the numbers are from [1..n], i.e. zero does not appear. In fact, while looping through the array, we can test if zero was found and return immediately if not.
Now consider:
sum(A) = n (n + 1) / 2 - X + R
product(A) = n! R / X
where product(A) is the product of all element in A skipping the zero. We have two equations in two unknowns from which X and R can be derived algebraically.
Edit: by popular demand, here is a worked-out example:
Let's set:
S = sum(A) - n (n + 1) / 2
P = n! / product(A)
Then our equations become:
R - X = S
X = R P
which can be solved to:
R = S / (1 - P)
X = P R = P S / (1 - P)
Example:
A = [0 1 2 2 4]
n = A.length - 1 = 4
S = (1 + 2 + 2 + 4) - 4 * 5 / 2 = -1
P = 4! / (1 * 2 * 2 * 4) = 3 / 2
R = -1 / (1 - 3/2) = -1 / -1/2 = 2
X = 3/2 * 2 = 3
You could proceed as follows:
sort your array by using a Linear-time sorting algorithm (e.g. Counting sort) - O(N)
scan the sorted array and stop as soon as two consecutive elements are equal - O(N)
public class FindDuplicate {
public static void main(String[] args) {
// assume the array is sorted, otherwise first we have to sort it.
// time efficiency is o(n)
int elementData[] = new int[] { 1, 2, 3, 3, 4, 5, 6, 8, 8 };
int count = 1;
int element1;
int element2;
for (int i = 0; i < elementData.length - 1; i++) {
element1 = elementData[i];
element2 = elementData[count];
count++;
if (element1 == element2) {
System.out.println(element2);
}
}
}
}
public void duplicateNumberInArray {
int a[] = new int[10];
Scanner inp = new Scanner(System.in);
for(int i=1;i<=5;i++){
System.out.println("enter no. ");
a[i] = inp.nextInt();
}
Set<Integer> st = new HashSet<Integer>();
Set<Integer> s = new HashSet<Integer>();
for(int i=1;i<=5;i++){
if(!st.add(a[i])){
s.add(a[i]);
}
}
Iterator<Integer> itr = s.iterator();
System.out.println("Duplicate numbers are");
while(itr.hasNext()){
System.out.println(itr.next());
}
}
First of all creating an array of integer using Scanner class. Then iterating a loop through the numbers and checking if the number can be added to set (Numbers can be added to set only when that particular number should not be in set already, means set does not allow duplicate no. to add and return a boolean vale FALSE on adding duplicate value).If no. cannot be added means it is duplicate so add that duplicate number into another set, so that we can print later. Please note onething that we are adding the duplicate number into a set because it might be possible that duplicate number might be repeated several times, hence add it only once.At last we are printing set using Iterator.
//This is similar to the HashSet approach but uses only one data structure:
int[] a = { 1, 4, 6, 7, 4, 6, 5, 22, 33, 44, 11, 5 };
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<Integer, Integer>();
for (int i : a) {
map.put(i, map.containsKey(i) ? (map.get(i)) + 1 : 1);
}
Set<Entry<Integer, Integer>> es = map.entrySet();
Iterator<Entry<Integer, Integer>> it = es.iterator();
while (it.hasNext()) {
Entry<Integer, Integer> e = it.next();
if (e.getValue() > 1) {
System.out.println("Dupe " + e.getKey());
}
}
We can do using hashMap efficiently:
Integer[] a = {1,2,3,4,0,1,5,2,1,1,1,};
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int x : a)
{
if (map.containsKey(x)) map.put(x,map.get(x)+1);
else map.put(x,1);
}
Integer [] keys = map.keySet().toArray(new Integer[map.size()]);
for(int x : keys)
{
if(map.get(x)!=1)
{
System.out.println(x+" repeats : "+map.get(x));
}
}
This program is based on c# and if you want to do this program using another programming language you have to firstly change an array in accending order and compare the first element to the second element.If it is equal then repeated number found.Program is
int[] array=new int[]{1,2,3,4,5,6,7,8,9,4};
Array.Sort(array);
for(int a=0;a<array.Length-1;a++)
{
if(array[a]==array[a+1]
{
Console.WriteLine("This {0} element is repeated",array[a]);
}
}
Console.WriteLine("Not repeated number in array");
sort the array O(n ln n)
using the sliding window trick to traverse the array O(n)
Space is O(1)
Arrays.sort(input);
for(int i = 0, j = 1; j < input.length ; j++, i++){
if( input[i] == input[j]){
System.out.println(input[i]);
while(j < input.length && input[i] == input[j]) j++;
i = j - 1;
}
}
Test case int[] { 1, 2, 3, 7, 7, 8, 3, 5, 7, 1, 2, 7 }
output 1, 2, 3, 7
Traverse through the array and check the sign of array[abs(array[i])], if positive make it as negative and if it is negative then print it, as follows:
import static java.lang.Math.abs;
public class FindRepeatedNumber {
private static void findRepeatedNumber(int arr[]) {
int i;
for (i = 0; i < arr.length; i++) {
if (arr[abs(arr[i])] > 0)
arr[abs(arr[i])] = -arr[abs(arr[i])];
else {
System.out.print(abs(arr[i]) + ",");
}
}
}
public static void main(String[] args) {
int arr[] = { 4, 2, 4, 5, 2, 3, 1 };
findRepeatedNumber(arr);
}
}
Reference: http://www.geeksforgeeks.org/find-duplicates-in-on-time-and-constant-extra-space/
As described,
You have an array of numbers from 0 to n-1, one of the numbers is
removed, and replaced with a number already in the array which makes a
duplicate of that number.
I'm assuming elements in the array are sorted except the duplicate entry. If this is the scenario , we can achieve the goal easily as below :
public static void main(String[] args) {
//int arr[] = { 0, 1, 2, 2, 3 };
int arr[] = { 1, 2, 3, 4, 3, 6 };
int len = arr.length;
int iMax = arr[0];
for (int i = 1; i < len; i++) {
iMax = Math.max(iMax, arr[i]);
if (arr[i] < iMax) {
System.out.println(arr[i]);
break;
}else if(arr[i+1] <= iMax) {
System.out.println(arr[i+1]);
break;
}
}
}
O(n) time and O(1) space ;please share your thoughts.
Here is the simple solution with hashmap in O(n) time.
#include<iostream>
#include<map>
using namespace std;
int main()
{
int a[]={1,3,2,7,5,1,8,3,6,10};
map<int,int> mp;
for(int i=0;i<10;i++){
if(mp.find(a[i]) == mp.end())
mp.insert({a[i],1});
else
mp[a[i]]++;
}
for(auto i=mp.begin();i!=mp.end();++i){
if(i->second > 1)
cout<<i->first<<" ";
}
}
int[] a = {5, 6, 8, 9, 3, 4, 2, 9 };
int[] b = {5, 6, 8, 9, 3, 6, 1, 9 };
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
Console.Write("Original Array manipulated at position {0} + "\t\n"
+ "and the element is {1} replaced by {2} ", i,
a[i],b[i] + "\t\n" );
break;
}
}
Console.Read();
///use break if want to check only one manipulation in original array.
///If want to check more then one manipulation in original array, remove break
This video If Programming Was An Anime is too fun not to share. It is the same problem and the video has the answers:
Sorting
Creating a hashmap/dictionary.
Creating an array. (Though this is partially skipped over.)
Using the Tortoise and Hare Algorithm.
Note: This problem is more of a trivia problem than it is real world. Any solution beyond a hashmap is premature optimization, except in rare limited ram situations, like embedded programming.
Furthermore, when is the last time you've seen in the real world an array where all of the variables within the array fit within the size of the array? Eg, if the data in the array is bytes (0-255) when do you have an array 256 elements or larger without nulls or inf within it, and you need to find a duplicate number? This scenario is so rare you will probably never get to use this trick in your entire career.
Because it is a trivia problem and is not real world the question, I'd be cautious accepting an offer from a company that asks trivia questions like this, because people will pass the interview by sheer luck instead of skill. This implies the devs there are not guaranteed to be skilled, which unless you're okay teaching your seniors skills, you might have a bad time.
int a[] = {2,1,2,3,4};
int b[] = {0};
for(int i = 0; i < a.size; i++)
{
if(a[i] == a[i+1])
{
//duplicate found
//copy it to second array
b[i] = a[i];
}
}

Categories

Resources