• [LeetCode]sum合集


    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 abc 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);
    87     for(int i = 0;i < n;i++){
    88         for(int j = 0;j < 3;j++)
    89             printf("%d ",as[i][j]);
    90         printf("
    ");
    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
    ",sum);
    49 }

    4.4Sum

    题目:

    Given an array S of n integers, are there elements abc, 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);
        for(int i = 0;i < n;i++){
            for(int j = 0;j < 4;j++)
                printf("%d ",as[i][j]);
            printf("
    ");
        }
    
        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
    ",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("
    ");
        }
    
        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
    ",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("
    ");
    137     }
    138 
    139     free(length);
    140     free(ret);
    141 }

    题目:Combination Sum III

    从1-9中找k个不同的数保证其和为n。返回所有符合要求的组合。

    思路:

    通过递归找k个元素求和,和不等于n或个数大于k,则回溯。

    void LeetCode::combinationSum(vector<vector<int>>&result, vector<int>& arr, int k, int n){
        if (arr.size() == k && !n){//找到一个可行的结果
            result.push_back(arr);
            return;
        }
        if (arr.size() >= k)return;//没有合适的
        int i = arr.size() ? arr.at(arr.size() - 1) + 1: 1;//从最后一个元素的后一个数开始
        for (; i <= 9 && n - i >= 0; ++i){
            arr.push_back(i);//装入
            combinationSum(result, arr, k, n - i);//递归找下一个
            arr.pop_back();
        }
    }
    
    vector<vector<int>> LeetCode::combinationSum3(int k, int n){
        vector<vector<int>>result;
        vector<int>arr;
        combinationSum(result, arr, k, n);
        return result;
    }

    持续更新...

  • 相关阅读:
    封装异常处理之坑
    30multipart/form-data和application/x-www-form-urlencoded的区别(二)urlencoded之自动deocde
    使用MAT时的Shallow Size和 Retained Size的区别
    当动态代理遇到ioc
    线程池的原理
    synchroned原理与对象头(yet)
    mysql压力测试与qps监控
    一种mysql jvm死锁
    Android Jni变量对照表
    结构体中使用函数指针
  • 原文地址:https://www.cnblogs.com/yeqluofwupheng/p/6661410.html
Copyright © 2020-2023  润新知