简体   繁体   中英

Removing duplicates from a sorted array IN-PLACE without allocating space for a second array

I'm tasked with a perplexing problem. I'm attempting to turn an unsorted array with duplicates into a sorted array without duplicates. I used the selection sort to accomplish the first part:

public static void SelectionSort(int [] list) {
        int i = 0;
        int j = 0;

        int indexSmallest = 0;
        int temp = 0;

        for (i = 0; i < list.length - 1; i++) {
            indexSmallest = i;
            for (j = i + 1; j < list.length; j++) {
                if (list[j] < list[indexSmallest]) {
                    indexSmallest = j;
                }
            }

            temp = list[i];
            list[i] = list[indexSmallest];
            list[indexSmallest] = temp;
        }

    }

The sorting isn't the issue - I'm having a hard time removing the duplicates from the array. The solution that I have in my head is to create a secondary array, and iterate through the input to check if that element exists in the second array, if not, add it to the array. I'm stuck because I'm not able to create another array. So, what gives? How do I solve this problem if I can't create an array to cross-reference and check if I have unique values? I'm not able to use any built-in Java functions.

There is no need of second array ... think about it this way ...

The easiest way is to convert it to set / hashset and then sort it in an array.

But if the sets are forbidden, the only possibility is to put the duplicates at the end, cut them out and then sort the rest.

[1,8,1,2,3,5,3] in this array, you need to remove elements that are duplicates ... okay ... so what if we did something like this ... we will "split" this array into "sorted", "unsorted and duplicates" and "duplicates". Now what we will do is that we will go through the array using 2 pointers. One at the first element (lets call it "i" ) and at the last element (lets call it "j" ) ... now we will go while i < j and we will swap everytime, when we will find a duplicate. This way, you will get everything not duplicate before "i" and everything that is dupicate after "i" ... now you will sort the array from index 0 do index i and you should have sorted array and you will just cut out the duplicates ...

ofc., this will require the time complexity, to be able to handle O(n*logn) / O(n^2) ...

There is a way how to do it in a O(n), and that can be done by that .. you will use 2 pointers ...

one will be pointing at current sorted array, where you have no duplicates and toher will be pointing to a place, where are yet unswapped integers ... (you need to remember the highest number found)

to be more specific:

[1,2,2,3,3,4,5]
i = 0, j = 1
- fine
i = 1, j = 2
- duplicate ... soo ..
jumping to duplicate position
i = 2, j = 3 (array[3] != 2, so we will swap)
current array -> [1,2,3,2,3,4,5]
                      ^ ^  
                      i j
i = 3, j = 4 
- highest_number > 3 is not true (2 < 3), so skipping
i = 3, j = 5
- highest_number > 3 is not true (3 < 3), so skipping
i = 3, j = 6
- swapping
... etc

and you should end up with something like this
[1,2,3,4,5,2,3]
           ^ ^
           i j
now you can cut the array at i, so you will get `[1,2,3,4,5,\0]` (in C syntax) ... so basically `[1,2,3,4,5]`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM