0

I'm trying to make a method that counts the number of unique elements in an array. For example, if the array contains [1,2,3,4,5,1,5] there are 3 unique elements and my method should return the number 3.

This is what I´ve got so far:

static int numberOfUniqueIntegers(int[] number, int len) {
    int unique = 0;
    for (int i = 0; i < len; i++){
        int j;
        for (j = 0; j < i; j ++) {
            if (number[i] == number[j]) {
                break;
            }
        }
        if (i == j);
        unique++;
    }

    return unique;

}

The method takes in the array number and an integer len (which is the length of the array).

But in this case: [1,2,3,4,5,1,5] my method would return 5, instead of 3. I somehow need to check if the number has been repeated before, and if not unique++.

5
  • 2
    Sort the numbers in a copy array before counting Commented Jul 15, 2021 at 18:24
  • 2
    Java has a Set collection. This would fit your use case perfectly. Commented Jul 15, 2021 at 18:26
  • @Moritz Makowsi 's answer would be the best starting point. Best to use a debugger or output some logs to figure out what your code is doing. Commented Jul 15, 2021 at 18:37
  • Your question isn't clear. There are 5 unique elements in [1, 2, 3, 4, 5, 1, 5]: [1, 2, 3, 4, 5]. How are there only 3 ? What do you mean ? Commented Jul 15, 2021 at 19:04
  • @JonZarate There are 3 elements that appear only once. Commented Jul 15, 2021 at 19:30

8 Answers 8

4

You can create a frequency Map and then get the number of keys that have only one occurrence.

static int numberOfUniqueIntegers(int[] number) {
    Map<Integer, Long> freq = Arrays.stream(number).boxed().collect(
       Collectors.groupingBy(x -> x, Collectors.counting()));
    return (int) freq.entrySet().stream().filter(e -> e.getValue().equals(1L))
        .map(Map.Entry::getKey).count();
}

Demo

Sign up to request clarification or add additional context in comments.

Comments

0

This one should work, just retain the elements already seen in a separate array :

static int numberOfUniqueIntegers(int[] number, int len) {
    int unique = 0;
    List<Integer> temp = new ArrayList<>();
    for (int i = 0; i < len; i++){
        if (!temp.contains(number[i]))
        {
            unique ++;
            temp.add(number[i]);
        }
    }

    return unique;

}

2 Comments

This doesn't compile and would return 0.
Yes sorry, I taped my condition too quickly and missed the '!'. But I think your solution is better and more advance.
0
static int numberOfUniqueIntegers(int[] number, int len) {
    int unique = 0;
    boolean isRepeated;
    for (int i = 0; i < len; i++){
      isRepeated = false;//setting to defalut value
        int j;
        for (j = 0; j < len; j ++) {
          if(j == i) continue;
            if (number[i] == number[j]) {
              isRepeated = true;//if caught duplicate
                break;
            }
        }
        //if not caught duplicate then increment unique ++
        if(!isRepeated) unique++;
    }

    return unique;

}

What wen wrong?
You have to match every value with everyother value which you did not as because you are just using an array and there is no way to figure if futures values had a match in past. So, you have to cover the length of array and check each value against every value in it. if it was to be written using java collections then it be would much simpler and with less time complexity

1 Comment

Thanks for the feedback and thanks for the code! I like this of building code (even though I understand it's probably not the most efficient).
0

If you need to do this without using any additional space, e.g. a Set, then you have no option but to compare each element in the array against all others, an O(n^2) solution.

static int numberOfUniqueIntegers(int[] number, int len)
{
    int unique = 0;

    for (int i = 0; i < len; i++)
    {
        int j = 0;
        for (; j < len; j++)
            if (i != j && number[i] == number[j]) break;
        if (j == len) unique++;
    }

    return unique;

}

If you can use additional space then are options that use a Set.

1 Comment

Thank you!! This is exactly what I'm looking for!
0

You can try this with O(2n) complexity

static int numberOfUniqueIntegers() {
    //int[] abc = { 1, 2, 3, 4, 5, 1, 5 };

    int[] abc = { 1, 1, 1 };

    Map<Integer, Integer> st = new HashMap();
    int unique = 0;
    for (int i = 0; i < abc.length; i++) {
        if (st.isEmpty() || st.containsKey(abc[i])) {
            Integer vl = st.get(abc[i]);
            st.put(abc[i], Objects.nonNull(vl) ? (vl + 1) : 1);
        } else {
            st.put(abc[i], 1);
        }

    }
    for (int i : st.keySet()) {
        if (st.get(i) == 1) {
            unique = unique + 1;
        }
    }
    System.out.println(st);
    return unique;
}

Comments

0

The easiest way is to just use Set.

int[] s = { 1, 2, 1, 5, 3, 4, 5, 1, 1, 5 };
int count = numberOfUniqueIntegers(s);
System.out.println("Count = " + count);

Prints

Count = 3
  • Set#add returns false if element exists, true otherwise
  • if seen doesn't contain it, add to unique.
  • if it has already been seen, remove from unique.
  • only the unique ones will remain.
static int numberOfUniqueIntegers(int[] number) {
    Set<Integer> seen = new HashSet<>();
    Set<Integer> unique = new HashSet<>();
    for (int i : number) {
        if (!seen.add(i)) {
            unique.remove(i);
            continue;
        }
        unique.add(i);
    }
    return unique.size();
}

Due to the nature of Set the above works in O(n) and no explicit counting of elements needs to be done.

Comments

-1

Normally asking questions like this, many stack overflow answers will give you solutions, however, that might not be conducive to working through the problem yourself.

Keep in mind there are multiple ways to solve this kind of problem.

  • Use a Set (a data structure to deal specifically to deal with uniques)
  • Sort and count. On duplicates, move on.

Just want to point out a potential issue with your code. You are using a terminator on your conditional clause if(i == j);

Your code will compile and run correctly, however it will simply check the comparison and run count++ every time. You will want to fix this clause.

The correct syntax should be

if (i == j) {
   count++
} 

Check comment for the exact lines:

static int numberOfUniqueIntegers(int[] number, int len) {
    int unique = 0;
     for (int i = 0; i < len; i++){
        int j;
        for (j = 0; j < i; j ++) {
            if (number[i] == number[j]) {
                break;
            }
        }
        if (i == j); // This comparison is always ignored.
        unique++; // This line is always happening
    }

    return unique;

}

2 Comments

That still returns 5 for the input in the question.
Thank you very much for the feedback, didn't even notice I skipped the brackets..!
-1

You can use set

public static int numberOfUniqueIntegers(int[] number, int len) {

    Set<Integer> st = new HashSet();
    int unique = 0;
    for (int i = 0; i < len; i++) {

        if (!st.add(number[i])) {
            unique = unique - 1;
        } else {
            unique = unique + 1;
        }
    }

    return unique;
}

2 Comments

This returns -1 for {1, 1, 1}.
I am using here set just because of complexity, it should be O(n)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.