1

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.

Satheesh
  • 646
  • 1
  • 10
  • 33
  • 3
    Looks like you want to post to [Code Review](http://codereview.stackexchange.com/), SO isn't for improving upon working code and rather fixing broken code. – Spencer Wieczorek Mar 16 '17 at 18:47
  • Or you can look for answers to compare and see other solutions to test. [Removing Duplicates](http://stackoverflow.com/questions/10056729/java-remove-duplicates-from-an-array) – Mr00Anderson Mar 16 '17 at 18:51
  • @Underbalanced Please re-read the statement. The ask is to remove the item which has the duplicates. Inputs: (int list) data = [1, 2, 2, 3, 3, 3, 4, 5, 5] Output: (int list) [1, 4] – Satheesh Mar 17 '17 at 06:51
  • Why -1 for the question? I hope it's not a duplicate – Satheesh Mar 17 '17 at 09:12

2 Answers2

3

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.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
2

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();
sprinter
  • 27,148
  • 6
  • 47
  • 78
  • for java 8 you could use the more consise method for computing map values. for (int i = 0; i < input.length; i++) { counts.compute(input[i], (k, v) -> v == null ? 1 : v++); } – Mr00Anderson Mar 17 '17 at 11:17