|
| 1 | +/** |
| 2 | + * Return an array of arrays of size *returnSize. |
| 3 | + * The sizes of the arrays are returned as *returnColumnSizes array. |
| 4 | + * Note: Both returned array and *columnSizes array must be malloced, assume |
| 5 | + * caller calls free(). |
| 6 | + */ |
| 7 | + |
| 8 | +// Enumeration for more descriptive indexing into arrays |
| 9 | +enum QuickSortPositions { LEFT_MOST, RIGHT_MOST }; |
| 10 | +enum AnswerArrayIndex { ARRAY_ONE, ARRAY_TWO }; |
| 11 | + |
| 12 | +// Prototypes |
| 13 | +void quicksort(int *nums, int numsSize); |
| 14 | +void _quicksort(int *array, int array_length, int left, int right); |
| 15 | +int *partition3(int *array, int left, int right); |
| 16 | +void swap(int *first_value, int *second_value); |
| 17 | + |
| 18 | +int **createAnswerArray(int nums1Size, int nums2Size); |
| 19 | +void skipRepeatedValues(int *nums, int *numsCurrentIndex, int numsSize); |
| 20 | +int hasNotReachedTheEndOfOneOfTheArrays(int nums1CurrentIndex, int nums1Size, |
| 21 | + int nums2CurrentIndex, int nums2Size); |
| 22 | +void processArrays(int *nums1, int nums1Size, int *nums2, int nums2Size, |
| 23 | + int *answerArrayOne, int *answerArrayTwo, |
| 24 | + int *answerArrayOneSize, int *answerArrayTwoSize); |
| 25 | + |
| 26 | +int **findDifference(int *nums1, int nums1Size, int *nums2, int nums2Size, |
| 27 | + int *returnSize, int **returnColumnSizes) { |
| 28 | + // Preparing return values |
| 29 | + *returnSize = 2; |
| 30 | + *returnColumnSizes = (int *)calloc(*returnSize, sizeof(int)); |
| 31 | + int *answerArrayOneSize = &(*returnColumnSizes)[ARRAY_ONE]; |
| 32 | + int *answerArrayTwoSize = &(*returnColumnSizes)[ARRAY_TWO]; |
| 33 | + |
| 34 | + int **answer = createAnswerArray(nums1Size, nums2Size); |
| 35 | + int *answerArrayOne = answer[ARRAY_ONE]; |
| 36 | + int *answerArrayTwo = answer[ARRAY_TWO]; |
| 37 | + |
| 38 | + // This approach needs sorted arrays |
| 39 | + quicksort(nums1, nums1Size); |
| 40 | + quicksort(nums2, nums2Size); |
| 41 | + |
| 42 | + // Populate the answer arrays |
| 43 | + processArrays(nums1, nums1Size, nums2, nums2Size, answerArrayOne, |
| 44 | + answerArrayTwo, answerArrayOneSize, answerArrayTwoSize); |
| 45 | + |
| 46 | + return answer; |
| 47 | +} |
| 48 | + |
| 49 | +void processArrays(int *nums1, int nums1Size, int *nums2, int nums2Size, |
| 50 | + int *answerArrayOne, int *answerArrayTwo, |
| 51 | + int *answerArrayOneSize, int *answerArrayTwoSize) { |
| 52 | + int nums1CurrentIndex = 0; |
| 53 | + int nums2CurrentIndex = 0; |
| 54 | + |
| 55 | + while (hasNotReachedTheEndOfOneOfTheArrays(nums1CurrentIndex, nums1Size, |
| 56 | + nums2CurrentIndex, nums2Size)) { |
| 57 | + skipRepeatedValues(nums1, &nums1CurrentIndex, nums1Size); |
| 58 | + skipRepeatedValues(nums2, &nums2CurrentIndex, nums2Size); |
| 59 | + |
| 60 | + if (nums1[nums1CurrentIndex] == nums2[nums2CurrentIndex]) { |
| 61 | + nums1CurrentIndex++; |
| 62 | + nums2CurrentIndex++; |
| 63 | + } else if (nums1[nums1CurrentIndex] < nums2[nums2CurrentIndex]) |
| 64 | + answerArrayOne[(*answerArrayOneSize)++] = nums1[nums1CurrentIndex++]; |
| 65 | + else |
| 66 | + answerArrayTwo[(*answerArrayTwoSize)++] = nums2[nums2CurrentIndex++]; |
| 67 | + } |
| 68 | + |
| 69 | + // Populate remaining unique elements |
| 70 | + while (nums1CurrentIndex < nums1Size) { |
| 71 | + skipRepeatedValues(nums1, &nums1CurrentIndex, nums1Size); |
| 72 | + answerArrayOne[(*answerArrayOneSize)++] = nums1[nums1CurrentIndex++]; |
| 73 | + } |
| 74 | + while (nums2CurrentIndex < nums2Size) { |
| 75 | + skipRepeatedValues(nums2, &nums2CurrentIndex, nums2Size); |
| 76 | + answerArrayTwo[(*answerArrayTwoSize)++] = nums2[nums2CurrentIndex++]; |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +// Helper Functions |
| 81 | +void skipRepeatedValues(int *nums, int *numsCurrentIndex, int numsSize) { |
| 82 | + while (*numsCurrentIndex < numsSize - 1 && |
| 83 | + nums[*numsCurrentIndex] == nums[*numsCurrentIndex + 1]) { |
| 84 | + (*numsCurrentIndex)++; |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +int hasNotReachedTheEndOfOneOfTheArrays(int nums1CurrentIndex, int nums1Size, |
| 89 | + int nums2CurrentIndex, int nums2Size) { |
| 90 | + return nums1CurrentIndex < nums1Size && nums2CurrentIndex < nums2Size; |
| 91 | +} |
| 92 | + |
| 93 | +int **createAnswerArray(int nums1Size, int nums2Size) { |
| 94 | + int **answer = (int **)malloc(2 * sizeof(int *)); |
| 95 | + answer[ARRAY_ONE] = (int *)malloc(nums1Size * sizeof(int)); |
| 96 | + answer[ARRAY_TWO] = (int *)malloc(nums2Size * sizeof(int)); |
| 97 | + return answer; |
| 98 | +} |
| 99 | + |
| 100 | +// QuickSort Implementation |
| 101 | +void quicksort(int *nums, int numsSize) { |
| 102 | + _quicksort(nums, numsSize, 0, numsSize - 1); |
| 103 | +} |
| 104 | + |
| 105 | +void _quicksort(int *array, int array_length, int left, int right) { |
| 106 | + while (left < right) { |
| 107 | + int *middle = partition3(array, left, right); |
| 108 | + if (middle[LEFT_MOST] - left < right - middle[RIGHT_MOST]) { |
| 109 | + _quicksort(array, array_length, left, middle[LEFT_MOST] - 1); |
| 110 | + left = middle[RIGHT_MOST] + 1; |
| 111 | + } else { |
| 112 | + _quicksort(array, array_length, middle[RIGHT_MOST] + 1, right); |
| 113 | + right = middle[LEFT_MOST] - 1; |
| 114 | + } |
| 115 | + free(middle); |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +int *partition3(int *array, int left, int right) { |
| 120 | + int pivot_position = left + (right - left) / 2; |
| 121 | + int pivot = array[pivot_position]; |
| 122 | + swap(&array[left], &array[pivot_position]); |
| 123 | + |
| 124 | + int *middle = (int *)malloc(2 * sizeof(int)); |
| 125 | + |
| 126 | + middle[LEFT_MOST] = left; |
| 127 | + middle[RIGHT_MOST] = left; |
| 128 | + |
| 129 | + for (int i = left + 1; i <= right; ++i) { |
| 130 | + if (array[i] == pivot) { |
| 131 | + middle[RIGHT_MOST]++; |
| 132 | + swap(&array[middle[RIGHT_MOST]], &array[i]); |
| 133 | + } |
| 134 | + if (array[i] < pivot) { |
| 135 | + middle[LEFT_MOST]++; |
| 136 | + middle[RIGHT_MOST]++; |
| 137 | + swap(&array[middle[RIGHT_MOST]], &array[i]); |
| 138 | + swap(&array[middle[LEFT_MOST]], &array[middle[RIGHT_MOST]]); |
| 139 | + } |
| 140 | + } |
| 141 | + swap(&array[left], &array[middle[LEFT_MOST]]); |
| 142 | + return middle; |
| 143 | +} |
| 144 | + |
| 145 | +void swap(int *first_value, int *second_value) { |
| 146 | + int tmp_value = *first_value; |
| 147 | + *first_value = *second_value; |
| 148 | + *second_value = tmp_value; |
| 149 | +} |
0 commit comments