|
| 1 | +# Question |
| 2 | +Given an array of positive integers (possibly with duplicates) such that the numbers have been sorted only by 28 most significant bits. Sort the array completely. |
| 3 | + |
| 4 | +Example 1: |
| 5 | + |
| 6 | +Input: [0, 15, 12, 17, 18, 19, 33, 32] |
| 7 | +Output: [0, 12, 15, 17, 18, 19, 32, 33] |
| 8 | + |
| 9 | +``` |
| 10 | +Explanation: |
| 11 | +The integers in their binary representation are: |
| 12 | + 0 = 0000 0000 0000 0000 0000 0000 0000 0000 |
| 13 | +15 = 0000 0000 0000 0000 0000 0000 0000 1111 |
| 14 | +12 = 0000 0000 0000 0000 0000 0000 0000 1100 |
| 15 | +17 = 0000 0000 0000 0000 0000 0000 0001 0001 |
| 16 | +18 = 0000 0000 0000 0000 0000 0000 0001 0010 |
| 17 | +19 = 0000 0000 0000 0000 0000 0000 0001 0011 |
| 18 | +33 = 0000 0000 0000 0000 0000 0000 0010 0001 |
| 19 | +32 = 0000 0000 0000 0000 0000 0000 0010 0000 |
| 20 | +
|
| 21 | +In sorted order: |
| 22 | + 0 = 0000 0000 0000 0000 0000 0000 0000 0000 |
| 23 | +12 = 0000 0000 0000 0000 0000 0000 0000 1100 |
| 24 | +15 = 0000 0000 0000 0000 0000 0000 0000 1111 |
| 25 | +17 = 0000 0000 0000 0000 0000 0000 0001 0001 |
| 26 | +18 = 0000 0000 0000 0000 0000 0000 0001 0010 |
| 27 | +19 = 0000 0000 0000 0000 0000 0000 0001 0011 |
| 28 | +32 = 0000 0000 0000 0000 0000 0000 0010 0000 |
| 29 | +33 = 0000 0000 0000 0000 0000 0000 0010 0001 |
| 30 | +``` |
| 31 | + |
| 32 | +``` |
| 33 | +Example 2: |
| 34 | +
|
| 35 | +Input: [100207, 100205, 100204, 100206, 100203] |
| 36 | +Output: [100203, 100204, 100205, 100206, 100207] |
| 37 | +Explanation: |
| 38 | +The integers in their binary representation are: |
| 39 | +100207 = 0000 0000 0000 0001 1000 0111 0110 1111 |
| 40 | +100205 = 0000 0000 0000 0001 1000 0111 0110 1101 |
| 41 | +100204 = 0000 0000 0000 0001 1000 0111 0110 1100 |
| 42 | +100206 = 0000 0000 0000 0001 1000 0111 0110 1110 |
| 43 | +100203 = 0000 0000 0000 0001 1000 0111 0110 1011 |
| 44 | +
|
| 45 | +In sorted order: |
| 46 | +100203 = 0000 0000 0000 0001 1000 0111 0110 1011 |
| 47 | +100204 = 0000 0000 0000 0001 1000 0111 0110 1100 |
| 48 | +100205 = 0000 0000 0000 0001 1000 0111 0110 1101 |
| 49 | +100206 = 0000 0000 0000 0001 1000 0111 0110 1110 |
| 50 | +100207 = 0000 0000 0000 0001 1000 0111 0110 1111 |
| 51 | +``` |
| 52 | + |
| 53 | +Expected O(n) time solution. |
| 54 | + |
| 55 | +## Solution |
| 56 | + |
| 57 | +- Runtime: O(N) |
| 58 | +- Space: O(1), assuming result doesn't use space |
| 59 | +- N = Number of elements in array |
| 60 | + |
| 61 | +The idea is to use bucket sort, since the array is already partially sorted by the first 28 bits. |
| 62 | +During this time, we will place the numbers into 1 of 16 buckets based on the last 4 bits. |
| 63 | +We can just iterate from left to right until the first 28 bits are different. |
| 64 | +Then we can save the results we have in the buckets and reset. |
| 65 | +With this approach, we will never need more than 16 buckets at a given time. |
| 66 | + |
| 67 | +``` |
| 68 | +def sort_partial_sorted_28b(nums): |
| 69 | + if len(nums) == 0: |
| 70 | + return nums |
| 71 | + mask = ~0 << 4 |
| 72 | + curr_28b = nums[0] & mask |
| 73 | + buckets = [0] * 16 # 16 buckets -> n occurances |
| 74 | + results = list() |
| 75 | + for num in nums: |
| 76 | + if (num & mask) != curr_28b: # start sort |
| 77 | + for bucket, occurance in enumerate(buckets): |
| 78 | + for o in range(occurance): |
| 79 | + results.append(curr_28b | bucket) |
| 80 | + curr_28b = num & mask # set to next 28 bit group |
| 81 | + buckets = [0] * 16 # reset |
| 82 | + # add to buckets |
| 83 | + buckets[num & 15] += 1 |
| 84 | + for bucket, occurance in enumerate(buckets): |
| 85 | + for o in range(occurance): |
| 86 | + results.append(curr_28b | bucket) |
| 87 | + return results |
| 88 | +``` |
0 commit comments