同步发于 JuzerTech 网站,里面有我软、硬件学习的纪录与科技产品开箱,欢迎进去观看。
题目为给定一串数字,输出所有三个数字相加为 0 的数字组合。
这题有速度的问题,建议使用排序与搜寻方法。
题目与范例如下
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Example 2:
Input: nums = []
Output: []
Example 3:
Input: nums = [0]
Output: []
Constraints:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
解题策略为先排序,这样在 for 回圈时能跳过三个都是正整数的组合。
我采用的排序法是 merge sort , sortsub是用于 merge sort 的递归函式。
程式碼中採用了兩層的 for 第一層控制第一個數字 ( i ), 從 0 ~ ( n - 3 ) , for 的第二層控制第二個數字 ( j ), 從 ( i + 1 ) ~ ( n - 2 ) ,第三個數字透過搜尋法尋找,我採用的是二元搜尋法。
依序输出找到的数字组合。
下方为我的代码
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
void mergeSort(int* num, int numsSize);
void sortsub(int* num, int low, int high);
void merge(int* num, int low, int middleL, int middleR, int high);
bool binarySearch(int* nums, int left, int right, int target);
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
*returnSize = 0; // number of return pairs
int step = 512; // each memory alloc
*returnColumnSizes = (int*)malloc(sizeof(int*)*step);
int** re = (int**)malloc(sizeof(int*)*step);
mergeSort(nums, numsSize);
for(int i = 0; i<numsSize-2 ; i++){
if(i!=0){ //Jump Same num
while(i<numsSize-2){
if(nums[i]==nums[i-1])
i++;
else
break;
}
}
if(i<numsSize-2){
for(int j = i+1; j<numsSize-1 ; j++ ){
if(j!=i+1){ //Jump Same num
while(j<numsSize-1){
if(nums[j]==nums[j-1])
j++;
else
break;
}
}
if(j<numsSize-1){
if(binarySearch(nums,j+1,numsSize-1,((nums[i]+nums[j])*(-1)))){
if((*returnSize) != 0 && (*returnSize)%step == 0){ // Create space
*returnColumnSizes = (int*)realloc(*returnColumnSizes, sizeof(int*) * ((*returnSize)+step));
re = (int**)realloc(re, sizeof(int*) * ((*returnSize)+step));
}
(*returnColumnSizes)[*returnSize] = 3;
re[*returnSize] = (int*)malloc(sizeof(int)*3);
re[*returnSize][0] = nums[i];
re[*returnSize][1] = nums[j];
re[*returnSize][2] = 0-nums[i]-nums[j];
(*returnSize)++;
}
}
}
}
}
return re;
}
void mergeSort(int* num, int numsSize) {
sortsub(num, 0, numsSize - 1);
}
void sortsub(int* num, int low, int high) {
if ((high - low) >= 1) {
int middleL = (low + high) / 2;
int middleR = middleL + 1;
sortsub(num, low, middleL);
sortsub(num, middleR, high);
merge(num,low,middleL,middleR,high);
}
}
void merge(int *num,int low,int middleL,int middleR, int high) {
int combinedIndex = 0, leftIndex = low, rightIndex = middleR;
int* tempArray = (int*)malloc(sizeof(int) * (high - low + 1));
while (leftIndex <= middleL && rightIndex <= high) {
if (num[leftIndex] < num[rightIndex]) {
tempArray[combinedIndex++] = num[leftIndex++];
}
else
tempArray[combinedIndex++] = num[rightIndex++];
}
if (leftIndex > middleL) {
while (rightIndex <= high) {
tempArray[combinedIndex++] = num[rightIndex++];
}
}
else {
while (leftIndex <= middleL) {
tempArray[combinedIndex++] = num[leftIndex++];
}
}
for (int i = low; i <= high; i++) {
num[i] = tempArray[i - low];
}
}
bool binarySearch(int* nums, int left, int right, int target) {
int middle;
if (target < nums[left] || target > nums[right])
return false;
while (left <= right) {
middle = (right + left) / 2;
if (nums[middle] == target) {
return true;
}
else if (target > nums[middle]) {
left = middle + 1;
}
else {
right = middle - 1;
}
}
return false;
}
下方为时间与空间之消耗
Runtime: 216 ms, faster than 25 % of C online submissions for Roman to Integer.
Memory Usage: 36.3 MB, less than 20.51 % of C online submissions for Roman to Integer.
( 本题一次配置的记忆体空间尽量大一点,太小需要多次配置记忆体会大幅提升执行的时间。 )