4
\$\begingroup\$

The problem is old and simple but I wanted to try it in a different way. With some extra memory I have created an OOP-based solution. Hopefully it doesn't hurt in the interview.

import java.util.*;
import java.lang.*;
import java.io.*;

class Main {
  static class Solution {
    private int[] items;
    private List<Integer> duplicates;

    Solution(int[] items) {
      this.items = items;
      this.duplicates = new ArrayList<>();
      if (items.length > 1) {
        solve();  
      }
    }

    private void solve() {
      Set<Integer> appeared = new HashSet<>();
      for (int item : items) {
        if (!appeared.add(item)) {
          duplicates.add(item);
        }
      }
    }

    public boolean hasDuplicate() {
      return duplicates.size() > 0 ? true : false;
    }
  }


  private static int[] readInput() {
    Scanner s = new Scanner(System.in);
    int N = s.nextInt();
    int[] arr = new int[N];

    for (int i = 0; i < N; i++) {
      arr[i] = s.nextInt();  
    }
    return arr;
  }

  private static void tests() {
    // Falsy
    System.out.println(new Solution(new int[]{}).hasDuplicate());
    System.out.println(new Solution(new int[]{1}).hasDuplicate());
    System.out.println(new Solution(new int[]{1, 2}).hasDuplicate());
    System.out.println(new Solution(new int[]{Integer.MIN_VALUE, Integer.MAX_VALUE}).hasDuplicate());

    // Truthy
    System.out.println(new Solution(new int[]{1, 1}).hasDuplicate());
    System.out.println(new Solution(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE}).hasDuplicate());
    System.out.println(new Solution(new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE}).hasDuplicate());
  }

  public static void main(String[] args) {
    //System.out.println(new Solution(readInput()).hasDuplicate());
    tests();
  }
}

Note: I cannot use JUnit or any testing framework during the interview.

\$\endgroup\$
5
\$\begingroup\$

Wasted memory

There is nothing in the description and the posted code to justify storing the input array and duplicates inside a class. This is a waste of memory.

If you just want to check if an array has duplicate values, you should do just that. This means you could return early as soon as you found the answer:

public boolean hasDuplicate(int[] items) {
  Set<Integer> appeared = new HashSet<>();
  for (int item : items) {
    if (!appeared.add(item)) {
      return true;
    }
  }
  return false;
}

It's worth noting that fully reading the items array is also a wasted memory. You might even get a follow-up question "what if there are more numbers to check than fit in memory?". Instead of fully reading this array, consider streaming options, for example passing a Scanner, or Iterator<Integer> to hasDuplicate, which will read one number at a time, avoiding unnecessary I/O and memory usage. Just don't forget to close the input resource in the caller method after the computation is finished.

Idiomatic expressions

This is both tedious and not idiomatic:

return duplicates.size() > 0 ? true : false;

Use boolean expressions directly, and use the isEmpty method of collections (and strings) to check for emptiness:

return !duplicates.isEmpty();

A word about testing

Note: I cannot use JUnit or any testing framework during the interview.

You cannot run a main method with tests either. You can write down proper unit tests during an interview just as you can write the main method you did with tests.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.