Move duplicates to the end of a sorted array
You need to have 2-3 pointers (indexes). i: the next unique elements will be put at this position j: linear traversal pointer on the list
private static void fix(int[] nums) {
int i = 0;
int j = 0;
while (j < nums.length) {
int k;
for (k = j + 1; k < nums.length && nums[k] == nums[j]; k++) {
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
j = k;
i++;
}
}
If your values are in limited range, there exists solution in O(n) time and O(1) space.
Determine the maximum value in array. Get some constant C > arraymax
, as example - C = 10
for your array.
Scan array, squeezing unique values and counting duplicates for every value. If value V
has K>0
duplicates, write V+C*K
instead of value.
At the next scan find values with duplicates, extract number of duplicates and write them after squeezed unique values.
def dedup(lst):
mx = max(lst) + 1
dupcnt = 0
delcnt = 0
start = 0
for i in range(1, len(lst) + 1):
if i == len(lst) or (lst[i] != lst[start]):
lst[start - delcnt] = lst[start] + dupcnt * mx
delcnt += dupcnt
start = i
dupcnt = 0
else:
dupcnt += 1
dupidx = len(lst) - delcnt
for i in range(0, len(lst) - delcnt):
dupcnt = lst[i] // mx
if dupcnt:
lst[i] %= mx
for j in range(dupidx, dupidx+dupcnt):
lst[j] = lst[i]
dupidx += dupcnt
return lst
print(dedup([1,2,2,2,3,4,4,5]))
>>> [1, 2, 3, 4, 5, 2, 2, 4]