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.
1 Answer 1
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.
Explore related questions
See similar questions with these tags.