How we could find max non-repeatable value in the array with a time ~O(N)
I was trying to do it during huge time, but I found only ~O(2N):
int solution(int[] A) {
List<Integer> arr = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
int max = 0;
for(int i = 0; i < A.length; i++) {
if(!set.add(A[i])) arr.add(A[i]);
}
for(int i = 0; i < A.length; i++) {
if (max < A[i] && !arr.contains(A[i])) max = A[i];
}
return max;
}
Could we do it a little bit faster?!
int A[] = {5, 5, 3, 2, 3, 1};
Map<Integer, Integer> map = new HashMap<>();
for(int i : A) {
Integer count = map.get(i);
// according to the comments
// map.merge(i, 1, Integer::sum)
map.put(i, count == null ? 1 : count + 1);
}
int max = 0;
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
if (e.getValue() == 1 && max < e.getKey()) {
max = e.getKey();
}
}
System.out.println(max);
Here you map each number to a number of times it present in the array.
In this case complexity is O(n).
And just out of integer possible the fastest implementation possible
// this code for academic purpose only
// it can work only with integers less than
// 2^nextPowerOfTwo(array.lenght) as
// hash collision doesn't resolved
public static int nextPowerOfTwo(int value) {
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
return ++value;
}
public static int findMaxUnique(int[] array) {
final int hashSize = nextPowerOfTwo(array.length);
final int[] hashArray = new int[hashSize];
for (int n : array) {
int hash = n ^ (n >>> 16);
hash &= hashSize - 1;
hashArray[hash]++;
}
int max = 0;
for (int n : array) {
int hash = n ^ (n >>> 16);
hash &= hashSize - 1;
if (hashArray[hash] == 1 && max < n) {
max = n;
}
}
return max;
}
public static void main(String[] args) {
int[] array = {5, 4, 5, 3, 1, 5, 4, 0};
System.out.println(findMaxUnique(array));
}
The idea is to count the number of occurrence, and store it in a treeMap.
since treeMap is sorted, we can find the last (biggest) number that is not repeated (value of 1)
//tree map is sorted... so the idea is to find the last item with value = 1
TreeMap<Integer,Integer> occurrence = new TreeMap<>();
//tabulate the number of occurrence of each key
//O(2N)
Stream.of(array).forEach( key ->
occurance.compute(key, (k, v) -> v == null ? 1 : v + 1));
//now that we have the treeMap with the number of occurrence,
//we can find the last non-repeated value.
while(!occurance.isEmpty()){
//iterate from the back up
Map.Entry<Integer,Integer> le = occurance.pollLastEntry(); //or var if JAVA10
if (le.getValue==1) return le.getKey();
}
//no unique numbers found
return Integer.MIN_VALUE;
You could probably sort your array in descending order using the Radix sort and then loop over it and check wheter currentIndex == currentIndex + 1
.
This will give you a maximum complexity of O(n*x)
which is basically the same as O(n)
if I'm not mistaking and still better than the actual O(n^2)
you're using