Satheesh
Satheesh

Reputation: 656

Remove duplicate elements from array along with element in Java 1.7

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.

  1. Copy the int array to ArrayList (inputList).
  2. Create a LinkedHashset to find unique values
  3. 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

Answers (2)

sprinter
sprinter

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

GhostCat
GhostCat

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

Related Questions