1

The problem to solve is to find a non-repeating integer in an Integer list. I used a while loop to compare each value with another. The function, however, returns the wrong value. This is a Hackerrank challenge which can be found here .

public static int lonelyinteger(List<Integer> a) {

int lonelyInt = 0;
for (int i = 0; i < a.size(); i++) {
    for (int j=1;j<a.size();j++){
        while (a.get(i)!=a.get(j)){
            lonelyInt+=a.get(i);
            
        }
    }
}
return lonelyInt;
}

I would really appreciate any hints and/or more straightforward solutions. I am new to Java and practicing my skills.

coding girl
  • 183
  • 3
  • 15
  • Why are you adding values to `lonelyInt` if the requirement is to find a specific element of the list? – UnholySheep Feb 17 '22 at 23:19
  • Why you are using while loop here? What is the purpose of lonelyInt variable? – Nemanja Feb 17 '22 at 23:20
  • I need to return an integer value, that's why the variable lonelyInt is needed.. I use the while loop to make sure a.get(i) doesn't equal a.get(j) to get the value that doesn't match another. – coding girl Feb 17 '22 at 23:24
  • Work through a small example on paper or using the debugger (maybe as simple as {1,1,2}). Does your algorithm work? What happens? – tgdavies Feb 17 '22 at 23:30
  • 1
    I'd use a set. Iterate through the array, and for each element, try adding it to the set. If it didn't get added (because it was there already), remove it instead. When you get to the end of the array, there should be one element left in the set, and that's the integer you're looking for. – Dawood ibn Kareem Feb 17 '22 at 23:37
  • 1
    XOR all the numbers. They either occur once or twice. The ones that occur twice cancel each other out on an xor, leaving you with the single lonely number – Erwin Bolwidt Feb 18 '22 at 00:03
  • @ErwinBolwidt That's very clever, of course. Clever solutions fall over when OP's professor/teacher asks her to explain how the solution works. – Dawood ibn Kareem Feb 18 '22 at 02:52
  • @DawoodibnKareem It's a hackerrank challenge, as the OP indicated, not a homework assignment. This is just a basic trick. I don't particularly like these types of tricks as they are not very relevant for 95% of real-world code. But it is the kind of result that they want you to come up with in hackerrank challenges. (The challenge is clearly specifically written for this solution, else it wouldn't limit the number of duplicate occurrences to 2) – Erwin Bolwidt Feb 18 '22 at 05:53
  • Yeah, I saw the hackerrank reference. But I have taught in a university. I know that a lazy professor might say "your assessment is to do hackerrank challenge 12345", or whatever. – Dawood ibn Kareem Feb 18 '22 at 07:29

4 Answers4

1

Your approach of comparing each number with all the other numbers is correct in principle.

If we compare the ith element of the array with all the other elements, and none are equal to it, then we know it is the unique number.

Your program is not doing this correctly.

Think of the loops like this:

  • The outer loop using the index i is giving us the number we are checking for loneliness, a.get(i).
  • The inner loop using the index j is giving us each number to check against the current candidate selected by the outer loop, a.get(j).

So for each iteration of the outer loop we will need to keep track of whether any iteration of the inner loop matched. We could use a local boolean named equalNumberFound, which we set to false at the start of each iteration of the outer loop.

In the inner loop, we check whether we've found an equal number, and if we have, set it to true. Make sure that you don't check a number against itself!

At the end of each iteration of the outer loop, we check equalNumberFound, and if it's still false we can return the current outer loop number, because we now know that no other number was equal.

You need to review what you know about while loops, as it seems you have some incorrect assumptions about how they behave.

tgdavies
  • 10,307
  • 4
  • 35
  • 40
1

One of the ways you could approach the problem is by sorting the list first then compare each element to its adjacent element since the elements are limited to occurring either once or twice. Since only one element occurs once, then the element without an identical adjacent element is the stop condition. This approach achieves O(log(N)) time complexity and O(1) space complexity.

public static int lonelyInteger(List<Integer> a) {
    Collections.sort(a);

    for (int i = 1; i < a.size(); i += 2) {
        if (a.get(i - 1).intValue() != a.get(i).intValue()) return a.get(i - 1);
    }
    return a.get(a.size()-1);
}
douglas
  • 116
  • 3
1

You can make use of hashset. Iterate through the list of integers:

  1. Add element to hashset, if integer is not present in the hashset.
  2. Remove the integer element, if it is already present in the hashset

Now return the lone non-repeating integer in the hashset.

public static int lonelyinteger(List<Integer> a) {
    
     Set<Integer> set = new HashSet<>();
          
     for (int n : a) {        
         if (set.contains(n)) {
            set.remove(n);
         } else {
            set.add(n);
         }        
     }
     return set.stream().findFirst().get();
}
tgdavies
  • 10,307
  • 4
  • 35
  • 40
Ajay V
  • 523
  • 5
  • 11
  • You don't need to use `contains`. Just use `add`. It returns `true` if it added something, and `false` if the thing you were adding was already there. – Dawood ibn Kareem Feb 18 '22 at 02:50
0

A better solution without using Streams

public static int lonelyinteger(List<Integer> a) {
    Set<Integer> s = new HashSet<>();
    for (int num : a) {
        if(!s.add(num)){
            s.remove(num);
        }
    }
    return new ArrayList<>(s).get(0);
}