|
1 | 1 | package com.thealgorithms.maths;
|
2 | 2 |
|
3 |
| -import java.util.Scanner; |
4 |
| - |
5 |
| -/* |
6 |
| - * Find the 2 elements which are non repeating in an array |
| 3 | +/** |
| 4 | + * Find the 2 elements which are non-repeating in an array |
7 | 5 | * Reason to use bitwise operator: It makes our program faster as we are operating on bits and not
|
8 | 6 | * on actual numbers.
|
| 7 | + * |
| 8 | + * Explanation of the code: |
| 9 | + * Let us assume we have an array [1, 2, 1, 2, 3, 4] |
| 10 | + * Property of XOR: num ^ num = 0. |
| 11 | + * If we XOR all the elements of the array, we will be left with 3 ^ 4 as 1 ^ 1 |
| 12 | + * and 2 ^ 2 would give 0. Our task is to find num1 and num2 from the result of 3 ^ 4 = 7. |
| 13 | + * We need to find the two's complement of 7 and find the rightmost set bit, i.e., (num & (-num)). |
| 14 | + * Two's complement of 7 is 001, and hence res = 1. There can be 2 options when we Bitwise AND this res |
| 15 | + * with all the elements in our array: |
| 16 | + * 1. The result will be a non-zero number. |
| 17 | + * 2. The result will be 0. |
| 18 | + * In the first case, we will XOR our element with the first number (which is initially 0). |
| 19 | + * In the second case, we will XOR our element with the second number (which is initially 0). |
| 20 | + * This is how we will get non-repeating elements with the help of bitwise operators. |
9 | 21 | */
|
10 | 22 | public final class NonRepeatingElement {
|
11 | 23 | private NonRepeatingElement() {
|
12 | 24 | }
|
13 | 25 |
|
14 |
| - public static void main(String[] args) { |
15 |
| - try (Scanner sc = new Scanner(System.in)) { |
16 |
| - int i; |
17 |
| - int res = 0; |
18 |
| - System.out.println("Enter the number of elements in the array"); |
19 |
| - int n = sc.nextInt(); |
20 |
| - if ((n & 1) == 1) { |
21 |
| - // Not allowing odd number of elements as we are expecting 2 non repeating |
22 |
| - // numbers |
23 |
| - System.out.println("Array should contain even number of elements"); |
24 |
| - return; |
25 |
| - } |
26 |
| - int[] arr = new int[n]; |
| 26 | + /** |
| 27 | + * Finds the two non-repeating elements in the array. |
| 28 | + * |
| 29 | + * @param arr The input array containing exactly two non-repeating elements and all other elements repeating. |
| 30 | + * @return An array containing the two non-repeating elements. |
| 31 | + * @throws IllegalArgumentException if the input array length is odd. |
| 32 | + */ |
| 33 | + public static int[] findNonRepeatingElements(int[] arr) { |
| 34 | + if (arr.length % 2 != 0) { |
| 35 | + throw new IllegalArgumentException("Array should contain an even number of elements"); |
| 36 | + } |
27 | 37 |
|
28 |
| - System.out.println("Enter " + n + " elements in the array. NOTE: Only 2 elements should not repeat"); |
29 |
| - for (i = 0; i < n; i++) { |
30 |
| - arr[i] = sc.nextInt(); |
31 |
| - } |
| 38 | + int xorResult = 0; |
32 | 39 |
|
33 |
| - // Find XOR of the 2 non repeating elements |
34 |
| - for (i = 0; i < n; i++) { |
35 |
| - res ^= arr[i]; |
36 |
| - } |
37 |
| - |
38 |
| - // Finding the rightmost set bit |
39 |
| - res = res & (-res); |
40 |
| - int num1 = 0; |
41 |
| - int num2 = 0; |
| 40 | + // Find XOR of all elements |
| 41 | + for (int num : arr) { |
| 42 | + xorResult ^= num; |
| 43 | + } |
42 | 44 |
|
43 |
| - for (i = 0; i < n; i++) { |
44 |
| - if ((res & arr[i]) > 0) { // Case 1 explained below |
45 |
| - num1 ^= arr[i]; |
46 |
| - } else { |
47 |
| - num2 ^= arr[i]; // Case 2 explained below |
48 |
| - } |
| 45 | + // Find the rightmost set bit |
| 46 | + int rightmostSetBit = xorResult & (-xorResult); |
| 47 | + int num1 = 0; |
| 48 | + int num2 = 0; |
| 49 | + |
| 50 | + // Divide the elements into two groups and XOR them |
| 51 | + for (int num : arr) { |
| 52 | + if ((num & rightmostSetBit) != 0) { |
| 53 | + num1 ^= num; |
| 54 | + } else { |
| 55 | + num2 ^= num; |
49 | 56 | }
|
50 |
| - |
51 |
| - System.out.println("The two non repeating elements are " + num1 + " and " + num2); |
52 | 57 | }
|
| 58 | + |
| 59 | + return new int[] {num1, num2}; |
53 | 60 | }
|
54 |
| - /* |
55 |
| - * Explanation of the code: |
56 |
| - * let us assume we have an array [1,2,1,2,3,4] |
57 |
| - * Property of XOR: num ^ num = 0. |
58 |
| - * If we XOR all the elemnets of the array we will be left with 3 ^ 4 as 1 ^ 1 |
59 |
| - * and 2 ^ 2 would give |
60 |
| - * 0. Our task is to find num1 and num2 from the result of 3 ^ 4 = 7. We need to |
61 |
| - * find two's |
62 |
| - * complement of 7 and find the rightmost set bit. i.e. (num & (-num)) Two's |
63 |
| - * complement of 7 is 001 |
64 |
| - * and hence res = 1. There can be 2 options when we Bitise AND this res with |
65 |
| - * all the elements in our |
66 |
| - * array |
67 |
| - * 1. Result will come non zero number |
68 |
| - * 2. Result will be 0. |
69 |
| - * In the first case we will XOR our element with the first number (which is |
70 |
| - * initially 0) |
71 |
| - * In the second case we will XOR our element with the second number(which is |
72 |
| - * initially 0) |
73 |
| - * This is how we will get non repeating elements with the help of bitwise |
74 |
| - * operators. |
75 |
| - */ |
76 | 61 | }
|
0 commit comments