Reputation: 21
For example, I am provided an array: 1, 3, 9, 6, 5, 8, 3, 4 The problem is that I have to find pairs whose sum is 9 in the array mentioned above. However, the pair must not be repetitive. This means if I already found the first pair [3, 6], then the second pair [6, 3] is not accepted.
The output of this problem should be [1, 8] [3, 6] [5, 4] (no [6, 3] because it is repetitive)
I use Java 8 to solve this problem.
Here are some codes that I tried:
public static void printSumNine(int[] input)
{
for (int i = 0; i < input.length - 1; i++) {
for (int j = i + 1; j < input.length; j++) {
if (9 - input[i] == input[j]) {
System.out.println("[" + input[i] + ", " + input[j] + "]");
}
}
}
}
Then I put this input in the parameter
int input[] = {1, 3, 9, 6, 5, 8, 3, 4};
I expect the output should be:
[1, 8]
[3, 6]
[5, 4]
but my code produces a different output:
[1, 8]
[3, 6]
[6, 3]
[5, 4]
Upvotes: 2
Views: 1506
Reputation: 1430
First,add repeated pairs check for your method,the method like this:
m+n=s
,assume m<n
,and n-m=x
m+n=m+m+x=s
x=s-2m
since m is different so the x is different so we can use x to identity the pairs,and every pair just need a bit to tag:
public static void printSumNine(int[] input) {
BitSet checkPool = new BitSet(input.length);
for (int i = 0; i < input.length - 1; i++) {
for (int j = i + 1; j < input.length; j++) {
if (9 - input[i] == input[j]) {
int checkSum = Math.abs(input[i] - input[j]);
if (!checkPool.get(checkSum)) {
checkPool.flip(checkSum);
System.out.println("[" + input[i] + ", " + input[j] + "]");
}
}
}
}
}
A common method to solve this problem and need costs nlog(n)
time and no need other memory:
public static void printSumNine(int[] input, int target) {
Arrays.sort(input);
for (int i = 0, j = input.length - 1; i < j; ) {
int sum = input[i] + input[j];
if (sum == target) {
System.out.println("[" + input[i] + ", " + input[j] + "]");
if (input[i + 1] == input[i]) {
i += 2;
} else {
i++;
}
} else if (sum > target) {
if (input[j - 1] == input[j]) {
j -= 2;
} else {
j--;
}
}
}
}
Upvotes: 0
Reputation: 880
Try this code. I've used a hashmap to store data. when printing i validate values in hashmap before printing.
public static void main(String[] args) {
int input[] = {1, 3, 9, 6, 5, 8, 3, 4};
Map<Integer, Integer> valueMap = new HashMap<>();
for (int i = 0; i < input.length - 1; i++) {
for (int j = i + 1; j < input.length; j++) {
if (9 - input[i] == input[j]) {
if((valueMap.containsKey(input[i])&&valueMap.containsValue(input[j])) || (valueMap.containsKey(input[j])&&valueMap.containsValue(input[i]))) {
//these are repetitive values
} else {
valueMap.put(input[i], input[j]);
System.out.println("[" + input[i] + ", " + input[j] + "]");
}
}
}
}
}
Upvotes: 0
Reputation: 1500
-----**UPDATE for a better solution **------
If you don't mind the order of numbers in pairs, I would suggest you using Set
and it needs only O(N) to finish your task better than O(NlogN) in the current solution.
Solution:
int N = 9;
Set<Integer> set = new HashSet<>();
int[] input = new int[] { 1, 3, 9, 6, 5, 8, 3, 4 };
for (int i = 0; i < input.length; i++) {
//condition N = input[i] * 2 is for some cases such as (N = 8, and array contains 2 numbers which have same value 4)
if (set.contains(N - input[i]) && (!set.contains(input[i]) || (N ==input[i] *2)) {
System.out.println(input[i] + " - " + (9 - input[i]));
}
set.add(input[i]);
}
The complexity of Hashset.contains is O(1) while you just need to run 1 loop to solve your problem.
I suggest using a Map
to remove the duplicate.
Map<Integer, Integer> usedMap
Here is my modified version. Even though its complexity is not good but it is workable. I will edit this post if I can find another approacher with a better complexity.
Map<Integer, Integer> usedMap = new HashMap<Integer, Integer>();
int[] input = new int[] { 1, 3, 9, 6, 5, 8, 3, 4 };
for (int i = 0; i < input.length - 1; i++) {
if (!usedMap.containsKey(input[i])) {
for (int j = i + 1; j < input.length; j++) {
if (!usedMap.containsKey(input[j])) {
if (9 - input[i] == input[j]) {
System.out.println("[" + input[i] + ", " + input[j] + "]");
usedMap.put(input[j], 1);
}
}
}
usedMap.put(input[i], 1);
}
}
Upvotes: 1