I'm trying to sort a array in place like [3,2,1,2,4,5,3] so that it is in sorted order ascending but with all duplicates grouped at the end in sorted order. So the result for the array would be [1,4,5,2,2,3,3]. How can I do this without using python built in sort()?
-
1Can you explain the in-place requirement? This seems like it's going to require at least some sort of auxiliary data structure that is potentially as large as the array.Samwise– Samwise2021-03-12 20:01:43 +00:00Commented Mar 12, 2021 at 20:01
-
By in place I mean insert into the original array by using multiple pointers and/or a temp variableEric Steen– Eric Steen2021-03-12 20:08:51 +00:00Commented Mar 12, 2021 at 20:08
Add a comment
|
2 Answers
You can specify the key argument as a tuple (whether value repeats, value itself):
sort(l, key=lambda v: (l.count(v) > 1, v))
UPD: This is fine for smaller lists. However, as @Stef mentioned in the comment, this solution has a quadratic complexity while you can do it in N * log(N):
from collections import Counter
c = Counter(l)
sort(l, key=lambda x: (c[x] > 1, x))
4 Comments
Stef
This counts the duplicates multiple times, resulting in a quadratic complexity. An alternative is:
from collections import Counter; c = Counter(l); sort(l, key=lambda x: (c[x] > 1, x))Yevhen Kuzmovych
@Stef, thanks, added your solution and explanation.
Stef
It doesn't have an N^2 log(N) complexity. Just N^2.
sort calls the key function only once per item in the list, before sorting.Yevhen Kuzmovych
@Stef Today I learned. Thanks, updated.
Do it in two phases.
- Just sort the array in-place with your favorite in-place sorting algorithm
- Scanning sorted array right to left, find the first
DUsubarray (whereDis a bunch of duplicate values, andUis a tail of unique elements). Make it intoUD. Keep going.
The second phase completes in O(n).