LeetCode很喜欢sum,里面sum题一堆。
1.Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
1 /** 2 * Note: The returned array must be malloced, assume caller calls free(). 3 */ 4 int* twoSum(int* nums, int numsSize, int target) { 5 int* ret = (int*)malloc(2*sizeof(int)); 6 int j = 1; 7 for(int i = 0;i < numsSize - 1;){ 8 if(nums[i] + nums[j] == target){ 9 ret[0] = i; 10 ret[1] = j; 11 break; 12 } 13 j++; 14 if(j == numsSize){ 15 i++; 16 j = i + 1; 17 } 18 } 19 return ret; 20 }
用hash_map使其复杂度减小到O(n)
vector<int> twoSum(vector<int>& nums, int target) { vector<int> ret; hash_map<int, int>arr; for (int i = 0; i < nums.size(); i++){ int rem = target - nums[i]; if (arr.find(rem) != arr.end()){ ret.push_back(i); ret.push_back(arr.at(rem)); return ret; } arr[nums[i]] = i; } return ret; }
2.3Sum
题目:
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
找3个数和为0的所有不同组合,数组元素只能用1次
1.不知道具体有多少种可能,用链表来存储,再转成数组
2.暴力搜索,可以先排序,加快速度
3.注意跳过重复情况
1 /************************************************* 2 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. 3 Note: The solution set must not contain duplicate triplets. 4 For example, given array S = [-1, 0, 1, 2, -1, -4], 5 A solution set is: 6 [ 7 [-1, 0, 1], 8 [-1, -1, 2] 9 ] 10 *************************************************/ 11 #include<stdio.h> 12 #include<stdlib.h> 13 14 int cmp(const void *a , const void *b){ 15 return *(int *)a > *(int *)b ? 1 : -1; 16 } 17 18 struct linklist{ 19 int *val; 20 struct linklist *next; 21 }; 22 23 /** 24 * Return an array of arrays of size *returnSize. 25 * Note: The returned array must be malloced, assume caller calls free(). 26 */ 27 int** threeSum(int* nums, int numsSize, int* returnSize) { 28 struct linklist *ts = NULL; 29 int i,n = 0,head,tail,sum = 0; 30 //排序加快搜索 31 qsort(nums,numsSize,sizeof(int),cmp); 32 //i、head、tail三个指针,暴力搜索所有可能 33 for(i = 0;i < numsSize;i++){ 34 head = i + 1; 35 tail = numsSize - 1; 36 while (head < tail) { 37 sum = nums[i] + nums[head] + nums[tail]; 38 if(sum == 0){//找到一种可能 39 n++; 40 struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); 41 p->val = (int *)malloc(3*sizeof(int)); 42 p->val[0] = nums[i]; 43 p->val[1] = nums[head]; 44 p->val[2] = nums[tail]; 45 p->next = ts; 46 ts = p; 47 head++; 48 tail--; 49 while(nums[head] == nums[head - 1])head++;//跳过重复的情况 50 while(nums[tail] == nums[tail + 1])tail--; 51 }else if(sum > 0){//过大 52 while(nums[tail] == nums[tail - 1])tail--; 53 tail--; 54 }else{//过小 55 while(nums[head] == nums[head + 1])head++; 56 head++; 57 } 58 } 59 while(nums[i] == nums[i + 1])i++;//跳过重复的情况 60 } 61 62 struct linklist *p = NULL; 63 int **as = (int **)malloc(n*sizeof(int *)); 64 for(i = 0;i < n;i++) 65 as[i] = (int *)malloc(3*sizeof(int)); 66 i = 0; 67 while(ts != NULL){ 68 as[i][0] = ts->val[0]; 69 as[i][1] = ts->val[1]; 70 as[i++][2] = ts->val[2]; 71 p = ts; 72 ts = ts->next; 73 p->next = NULL; 74 free(p->val); 75 free(p); 76 } 77 78 *returnSize = n; 79 return as; 80 } 81 82 int main(){ 83 int a[] = {-1,0,1,2,-1,-4}; 84 int n = 0; 85 int **as = threeSum(a,sizeof(a)/sizeof(int),&n); 86 printf("%d\n",n); 87 for(int i = 0;i < n;i++){ 88 for(int j = 0;j < 3;j++) 89 printf("%d ",as[i][j]); 90 printf("\n"); 91 } 92 93 for(int i = 0;i < n;i++){ 94 free(as[i]); 95 } 96 }
3.3Sum Closest
题目:
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
找3个数的和最接近目标数的组合。
1 /*************************************************************************************************** 2 Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. 3 For example, given array S = {-1 2 1 -4}, and target = 1. 4 The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). 5 **************************************************************************************************/ 6 #include <stdio.h> 7 #include <stdlib.h> 8 9 int cmp(const void *a , const void *b){ 10 return *(int *)a > *(int *)b ? 1 : -1; 11 } 12 13 int threeSumClosest(int* nums, int numsSize, int target) { 14 int bestdif = 2147483647,bestsum; 15 int dif,sum,i,head,tail; 16 17 qsort(nums,numsSize,sizeof(int),cmp); 18 19 for(i = 0;i < numsSize;i++){ 20 head = i + 1; 21 tail = numsSize - 1; 22 while(head < tail){ 23 sum = nums[i] + nums[head] + nums[tail]; 24 dif = sum - target;//求差值 25 if(dif == 0)return sum; 26 else if(dif > 0){ 27 tail--; 28 while(nums[tail] == nums[tail + 1])tail--; 29 }else{ 30 head++; 31 while(nums[head] == nums[head - 1])head++; 32 } 33 dif = abs(dif); 34 if(dif < bestdif){//比较是否比已知的结果好 35 bestdif = dif; 36 bestsum = sum; 37 } 38 } 39 while(nums[i] == nums[i + 1])i++; 40 } 41 return bestsum; 42 } 43 44 void main(){ 45 int nums[] = {-1,2,1,-4,0}; 46 int target = 1; 47 int sum = threeSumClosest(nums,sizeof(nums)/sizeof(int),target); 48 printf("%d\n",sum); 49 }
4.4Sum
题目:
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
找4个数和为目标数的所有不同组合,数组元素只能用1次
接着暴力搜索。
/*************************************************************************************************** Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. Note: The solution set must not contain duplicate quadruplets. For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ] ***************************************************************************************************/ #include<stdio.h> int cmp(const void *a , const void *b){ return *(int *)a > *(int *)b ? 1 : -1; } struct linklist{ int *val; struct linklist *next; }; /** * Return an array of arrays of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int** fourSum(int* nums, int numsSize, int target, int* returnSize) { struct linklist *fs = NULL; int i,j,head,tail,dif = 0,length = 0; qsort(nums,numsSize,sizeof(int),cmp);//排序 //i,j,head,tail四个游标,暴力搜索 for(i = 0;i < numsSize;i++){ for(j = i + 1;j < numsSize;j++){ head = j + 1;//head从j+1开始 tail = numsSize - 1; while(head < tail){ dif = nums[i] + nums[j] + nums[head] + nums[tail] - target; if(dif == 0){ length++; struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); p->val = (int *)malloc(4*sizeof(int)); p->val[0] = nums[i]; p->val[1] = nums[j]; p->val[2] = nums[head++]; p->val[3] = nums[tail--]; p->next = fs; fs = p; while(nums[head] == nums[head - 1])head++; while(nums[tail] == nums[tail + 1])tail--; }else if(dif > 0){//过大 while(nums[tail] == nums[tail - 1])tail--; tail--; }else{//过小 while(nums[head] == nums[head + 1])head++; head++; } } while(nums[j] == nums[j + 1])j++; } while(nums[i] == nums[i + 1])i++; } int **ret = (int **)malloc(length*sizeof(int *)); struct linklist *p = NULL; i = 0; while(fs != NULL){ p = fs; fs = fs->next; p->next = NULL; ret[i] = (int *)malloc(4*sizeof(int)); ret[i][0] = p->val[0]; ret[i][1] = p->val[1]; ret[i][2] = p->val[2]; ret[i++][3] = p->val[3]; free(p->val); free(p); } *returnSize = length; return ret; } void main(){ int a[] = {-1,0,1,2,-1,-4,0}; int n = 0,target = 0; int **as = fourSum(a,sizeof(a)/sizeof(int),target,&n); printf("%d\n",n); for(int i = 0;i < n;i++){ for(int j = 0;j < 4;j++) printf("%d ",as[i][j]); printf("\n"); } for(int i = 0;i < n;i++){ free(as[i]); } }
5.Combination Sum
题目:
Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7]
and target 7
,
A solution set is:
[ [7], [2, 2, 3] ]
从数组中找和是目标数的所有组合,数组元素可以使用多次
用递归的思想求解:首先排序,然后搜索数组所有元素,目标数减去当前元素作为新的目标数,再递归搜索新的目标数,知道目标数为0.
1.多种不同组合中可能有部分元素重合,所以,搜索到一种结果后,还要继续搜索。
2.找到符合情况的组合后才能给数组分配大小,所以要记录递归的层数,返回时,每层给数组附上各自的值。
3.注意链表头特殊处理。
/******************************************************************************* Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. For example, given candidate set [2, 3, 6, 7] and target 7, A solution set is: [ [7], [2, 2, 3] ] *******************************************************************************/ #include<stdio.h> #include<stdbool.h> struct linklist{ int *val;//存储符合要求的数的组合 int size;//数组大小 struct linklist *next; }; int cmp(const void *a , const void *b){ return *(int *)a > *(int *)b ? 1 : -1; } struct linklist *getTargetArray(int *candidates,int candidatesSize,int surplus,int start,int length){ struct linklist *head = NULL; struct linklist *tail = head; int subStrSize; //递增排序,目标数比当前值还小,后面的就更加不可能了 for(int i = start;i < candidatesSize && surplus >= candidates[i];i++){ if(surplus - candidates[i] == 0){//找到一种情况 struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); p->size = length + 1; p->val = (int *)malloc(p->size*sizeof(int)); p->val[length] = candidates[i]; p->next = head; head = p; }else{ if(tail == NULL){//第一个符合情况的出现时,得到链表头 tail = getTargetArray(candidates,candidatesSize,surplus - candidates[i],i,length + 1); if(tail != NULL){//如果找到了符合的情况,添加当前的数 head = tail; tail->val[length] = candidates[i]; } }else{ tail->next = getTargetArray(candidates,candidatesSize,surplus - candidates[i],i,length + 1); } while(tail != NULL && tail->next != NULL){ tail->next->val[length] = candidates[i]; tail = tail->next; } } } return head; } /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *columnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) { struct linklist *cs = NULL; struct linklist *tail = cs; int **retStr = NULL; int *subStr = NULL; int subStrSize,count = 0; qsort(candidates,candidatesSize,sizeof(int),cmp); //递增排序,目标数比当前值还小,后面的就更加不可能了 for(int i = 0;i < candidatesSize && target >= candidates[i];i++){ if(target - candidates[i] == 0){ struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); p->size = 1; p->val = (int *)malloc(sizeof(int)); p->val[0] = candidates[i]; p->next = cs; cs = p; count++; }else{ if(tail == NULL){//第一个符合情况的出现时,得到链表头 tail = getTargetArray(candidates,candidatesSize,target - candidates[i],i,1); if(tail != NULL){//如果找到了符合的情况,添加当前的数 cs = tail; tail->val[0] = candidates[i]; count++; } }else{ tail->next = getTargetArray(candidates,candidatesSize,target - candidates[i],i,1); } while(tail != NULL && tail->next != NULL){//如果找到了符合的情况,添加当前的数 tail->next->val[0] = candidates[i]; tail = tail->next; count++; } } } retStr = (int **)malloc(count*sizeof(int *)); *columnSizes = (int *)malloc(count*sizeof(int)); struct linklist *p = NULL; int i = 0; while(cs != NULL){ p = cs; cs = cs->next; p->next = NULL; retStr[i] = (int *)malloc(p->size*sizeof(int)); columnSizes[0][i] = p->size; for(int j = 0;j < p->size;j++)retStr[i][j] = p->val[j]; free(p->val); free(p); i++; } *returnSize = count; return retStr; } void main(){ int a[] = {2, 3}; int target = 6,size; int *length = NULL; int **ret = combinationSum(a,sizeof(a)/sizeof(int),target,&length,&size); printf("%d\n",size); for(int i = 0;i < size;i++){ for(int j = 0;j < length[i];j++){ printf("%d ",ret[i][j]); } free(ret[i]); printf("\n"); } free(length); free(ret); }
6.Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5]
and target 8
,
A solution set is:
[ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
从数组中找和是目标数的所有组合,数组元素可以使用1次
1 /*************************************************************************************************** 2 Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. 3 Each number in C may only be used once in the combination. 4 Note: 5 All numbers (including target) will be positive integers. 6 The solution set must not contain duplicate combinations. 7 For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, 8 A solution set is: 9 [ 10 [1, 7], 11 [1, 2, 5], 12 [2, 6], 13 [1, 1, 6] 14 ] 15 ***************************************************************************************************/ 16 #include<stdio.h> 17 #include<stdbool.h> 18 19 struct linklist{ 20 int *val; 21 int size; 22 struct linklist *next; 23 }; 24 25 int cmp(const void *a , const void *b){ 26 return *(int *)a > *(int *)b ? 1 : -1; 27 } 28 29 struct linklist *getTargetArray(int *candidates,int candidatesSize,int surplus,int start,int length){ 30 struct linklist *head = NULL; 31 struct linklist *tail = head; 32 int subStrSize; 33 for(int i = start + 1;i < candidatesSize && surplus >= candidates[i];i++){ 34 if(surplus - candidates[i] == 0){ 35 struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); 36 p->size = length + 1; 37 p->val = (int *)malloc(p->size*sizeof(int)); 38 p->val[length] = candidates[i]; 39 p->next = head; 40 head = p; 41 }else{ 42 if(tail == NULL){ 43 tail = getTargetArray(candidates,candidatesSize,surplus - candidates[i],i,length + 1); 44 if(tail != NULL){ 45 head = tail; 46 tail->val[length] = candidates[i]; 47 } 48 }else{ 49 tail->next = getTargetArray(candidates,candidatesSize,surplus - candidates[i],i,length + 1); 50 } 51 while(tail != NULL && tail->next != NULL){ 52 tail->next->val[length] = candidates[i]; 53 tail = tail->next; 54 } 55 } 56 while(candidates[i] == candidates[i+1])i++; 57 } 58 59 return head; 60 } 61 62 /** 63 * Return an array of arrays of size *returnSize. 64 * The sizes of the arrays are returned as *columnSizes array. 65 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). 66 */ 67 int** combinationSum2(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) { 68 struct linklist *cs = NULL; 69 struct linklist *tail = cs; 70 int **retStr = NULL; 71 int *subStr = NULL; 72 int subStrSize,count = 0; 73 74 qsort(candidates,candidatesSize,sizeof(int),cmp); 75 76 for(int i = 0;i < candidatesSize && target >= candidates[i];i++){ 77 if(target - candidates[i] == 0){ 78 struct linklist *p = (struct linklist *)malloc(sizeof(struct linklist)); 79 p->size = 1; 80 p->val = (int *)malloc(sizeof(int)); 81 p->val[0] = candidates[i]; 82 p->next = cs; 83 cs = p; 84 count++; 85 }else{ 86 if(tail == NULL){ 87 tail = getTargetArray(candidates,candidatesSize,target - candidates[i],i,1); 88 if(tail != NULL){ 89 cs = tail; 90 tail->val[0] = candidates[i]; 91 count++; 92 } 93 }else{ 94 tail->next = getTargetArray(candidates,candidatesSize,target - candidates[i],i,1); 95 } 96 while(tail != NULL && tail->next != NULL){ 97 tail->next->val[0] = candidates[i]; 98 tail = tail->next; 99 count++; 100 } 101 } 102 while(candidates[i] == candidates[i+1])i++; 103 } 104 105 retStr = (int **)malloc(count*sizeof(int *)); 106 *columnSizes = (int *)malloc(count*sizeof(int)); 107 struct linklist *p = NULL; 108 int i = 0; 109 while(cs != NULL){ 110 p = cs; 111 cs = cs->next; 112 p->next = NULL; 113 retStr[i] = (int *)malloc(p->size*sizeof(int)); 114 columnSizes[0][i] = p->size; 115 for(int j = 0;j < p->size;j++)retStr[i][j] = p->val[j]; 116 free(p->val); 117 free(p); 118 i++; 119 } 120 121 *returnSize = count; 122 return retStr; 123 } 124 125 void main(){ 126 int a[] = {2,2,2}; 127 int target = 4,size; 128 int *length = NULL; 129 int **ret = combinationSum2(a,sizeof(a)/sizeof(int),target,&length,&size); 130 printf("%d\n",size); 131 for(int i = 0;i < size;i++){ 132 for(int j = 0;j < length[i];j++){ 133 printf("%d ",ret[i][j]); 134 } 135 free(ret[i]); 136 printf("\n"); 137 } 138 139 free(length); 140 free(ret); 141 }
持续更新...