How to efficiently remove duplicates from an array without using Set

后端 未结 30 2523
情深已故
情深已故 2020-11-22 07:29

I was asked to write my own implementation to remove duplicated values in an array. Here is what I have created. But after tests with 1,000,000 elements it took very long ti

相关标签:
30条回答
  • 2020-11-22 07:37

    I feel Android Killer's idea is great, but I just wondered if we can leverage HashMap. So I did a little experiment. And I found HashMap seems faster than HashSet.

    Here is code:

        int[] input = new int[1000000];
    
        for (int i = 0; i < input.length; i++) {
            Random random = new Random();
            input[i] = random.nextInt(200000);
        }
    
        long startTime1 = new Date().getTime();
        System.out.println("Set start time:" + startTime1);
    
        Set<Integer> resultSet = new HashSet<Integer>();
    
        for (int i = 0; i < input.length; i++) {
            resultSet.add(input[i]);
        }
    
        long endTime1 = new Date().getTime();
        System.out.println("Set end time:"+ endTime1);
        System.out.println("result of set:" + (endTime1 - startTime1));     
        System.out.println("number of Set:" + resultSet.size() + "\n");
    
        long startTime2 = new Date().getTime();
        System.out.println("Map start time:" + startTime1);
    
        Map<Integer, Integer> resultMap = new HashMap<Integer, Integer>();
    
        for (int i = 0; i < input.length; i++) {
            if (!resultMap.containsKey(input[i]))
                resultMap.put(input[i], input[i]);
        }
    
        long endTime2 = new Date().getTime();
        System.out.println("Map end Time:" + endTime2);
        System.out.println("result of Map:" + (endTime2 - startTime2));
        System.out.println("number of Map:" + resultMap.size());
    

    Here is result:

    Set start time:1441960583837
    Set end time:1441960583917
    result of set:80
    number of Set:198652
    
    Map start time:1441960583837
    Map end Time:1441960583983
    result of Map:66
    number of Map:198652
    
    0 讨论(0)
  • 2020-11-22 07:39

    Slight modification to the original code itself, by removing the innermost for loop.

    public static int[] removeDuplicates(int[] arr){
        int end = arr.length;
    
        for (int i = 0; i < end; i++) {
            for (int j = i + 1; j < end; j++) {
                if (arr[i] == arr[j]) {                  
                    /*int shiftLeft = j;
                    for (int k = j+1; k < end; k++, shiftLeft++) {
                        arr[shiftLeft] = arr[k];
                    }*/
                    arr[j] = arr[end-1];
                    end--;
                    j--;
                }
            }
        }
    
        int[] whitelist = new int[end];
        /*for(int i = 0; i < end; i++){
            whitelist[i] = arr[i];
        }*/
        System.arraycopy(arr, 0, whitelist, 0, end);
        return whitelist;
    }
    
    0 讨论(0)
  • 2020-11-22 07:39

    If you are allowed to use Java 8 streams:

    Arrays.stream(arr).distinct().toArray();
    
    0 讨论(0)
  • 2020-11-22 07:39

    I know this is kinda dead but I just wrote this for my own use. It's more or less the same as adding to a hashset and then pulling all the elements out of it. It should run in O(nlogn) worst case.

        public static int[] removeDuplicates(int[] numbers) {
        Entry[] entries = new Entry[numbers.length];
        int size = 0;
        for (int i = 0 ; i < numbers.length ; i++) {
            int nextVal = numbers[i];
            int index = nextVal % entries.length;
            Entry e = entries[index];
            if (e == null) {
                entries[index] = new Entry(nextVal);
                size++;
            } else {
                if(e.insert(nextVal)) {
                    size++;
                }
            }
        }
        int[] result = new int[size];
        int index = 0;
        for (int i = 0 ; i < entries.length ; i++) {
            Entry current = entries[i];
            while (current != null) {
                result[i++] = current.value;
                current = current.next;
            }
        }
        return result;
    }
    
    public static class Entry {
        int value;
        Entry next;
    
        Entry(int value) {
            this.value = value;
        }
    
        public boolean insert(int newVal) {
            Entry current = this;
            Entry prev = null;
            while (current != null) {
                if (current.value == newVal) {
                    return false;
                } else if(current.next != null) {
                    prev = current;
                    current = next;
                }
            }
            prev.next = new Entry(value);
            return true;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 07:41

    Note: I am assuming the array is sorted.

    Code:

    int[] input = new int[]{1, 1, 3, 7, 7, 8, 9, 9, 9, 10};
    int current = input[0];
    boolean found = false;
    
    for (int i = 0; i < input.length; i++) {
        if (current == input[i] && !found) {
            found = true;
        } else if (current != input[i]) {
            System.out.print(" " + current);
            current = input[i];
            found = false;
        }
    }
    System.out.print(" " + current);
    

    output:

      1 3 7 8 9 10
    
    0 讨论(0)
  • 2020-11-22 07:41
    public static void main(String args[]) {
        int[] intarray = {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5};
    
        Set<Integer> set = new HashSet<Integer>();
        for(int i : intarray) {
            set.add(i);
        }
    
        Iterator<Integer> setitr = set.iterator();
        for(int pos=0; pos < intarray.length; pos ++) {
            if(pos < set.size()) {
                intarray[pos] =setitr.next();
            } else {
                intarray[pos]= 0;
            }
        }
    
        for(int i: intarray)
        System.out.println(i);
    }
    
    0 讨论(0)
提交回复
热议问题