Reputation: 656
I need to write a method where a int[]
will be supplied as an input and it should return an array, but with all of the numbers that occur more than n times removed entirely.
Inputs:
(int list) data = [1, 2, 2, 3, 3, 3, 4, 5, 5]
Output:
(int list) [1, 4]
These are the steps i have tried.
Iterate LH and find the collection frequency of ArrayList with iterator.
int[] intArray = new int[0];
if(n!=0){
if(data.length<100){
ArrayList<Integer> inputList = new ArrayList<Integer>(data.length);
//System.out.println(Arrays.toString(data));
for (int i = 0; i < data.length; i++){
inputList.add(Integer.valueOf(data[i]));
}
LinkedHashSet<Integer> lhs = new LinkedHashSet<>(inputList);
intArray = new int[lhs.size()];
int i=0;
int j=0;
Iterator<Integer> itr = lhs.iterator();
while(itr.hasNext()){
Integer shiftNumber = itr.next();
if(Collections.frequency(inputList, shiftNumber)==1) {
intArray[i++] = shiftNumber.intValue();
j++;
}
}
intArray = Arrays.copyOf(intArray, j);
return intArray;
}
}
return intArray;
I am able to achieve the results with the above snippet.However, I need suggestions in reducing the piece of code and improving performance by using any algorithms or other collection objects.
Upvotes: 1
Views: 233
Reputation: 27976
You are likely overcomplicating the algorithm. It might be simpler to just map each value to its frequency and then copy those values with frequency less than n
. Also note that you don't need to explicitly covert between int
and Integer
: Java does it for you automatically.
int[] output = new int[input.length];
Map<Integer,Integer> counts = new HashMap<>();
int size = 0;
for (int i = 0; i < input.length; i++) {
counts.put(input[i], counts.getOrDefault(input[i], 0) + 1);
}
for (int i = 0; i < input.length; i++) {
if (counts.get(input[i]) < n)
output[size++] = input[i];
}
return Arrays.copyOf(output, size);
If you are familiar with Java 8 streams then the code can be substantially reduced:
Map<Integer,Integer> count = Arrays.stream(input).boxed()
.collect(groupingBy(identity(), counting()));
return Arrays.stream(input).filter(i -> count.get(i) < n).toArray();
Upvotes: 2
Reputation: 140505
You could use a map instead.
The map key would represent the values found in the array; the map value would be a counter.
You iterate your array, and for each element you either put a counter=1 (when finding that value the first time); or you simply increase that counter.
Finally, you collect only those map keys that show a counter value of 1.
Upvotes: 3