LeetCode刷题笔记- 15.三数之和

LeetCode刷题笔记- 15.三数之和

    • C语言
    • 题目
    • 注意点

C语言

/**
 * 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().
 */
#define VAL(ptr) (*(int *)ptr)

typedef struct ListNodeST {
    struct ListNodeST *next;
    int s;
    int e;
} ListNode;

int comp(const void *a, const void *b) {
    return  VAL(a) - VAL(b);
}

#define MAX_ONE(a,b) (a>b?a:b)
int isExists(struct ListNodeST *head, int s, int e) {
    if (s > e) {
        s ^= e;
        e ^= s;
        s ^= e;
    }
    while (head != NULL) {
        if (head->s == s && head->e == e) {
            return 1;
        }
        head = head->next;
    }
    return 0;
}
#define HASH_SIZE (1<<11)
#define HASH_MASK (HASH_SIZE-1)
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int i;
    int **ret = NULL;
    int s,e,vi,vs,ve,rsize = 0;
    int hmapsize = 1 << 3;
    struct ListNodeST *hmap[HASH_SIZE] = {NULL}, *tln = NULL;

    *returnSize = 0;
    ret = calloc(hmapsize, sizeof(int *));
    *returnColumnSizes = calloc(hmapsize, sizeof(int));
    
    qsort(nums, numsSize, sizeof(int), comp);
    for (i = 0; i < numsSize; i++) {
        s = i+1;
        e = numsSize-1;
        while( s < e) {
            vi = nums[i];
            vs = nums[s];
            ve = nums[e];
            if ((vi + vs + ve) == 0) {
                if(isExists(hmap[vi & HASH_MASK], vs, ve) == 1) {
                    s++;
                    continue;
                } 
                rsize+=1;
                if (rsize >= hmapsize) {
                    hmapsize = hmapsize << 1;
                    ret = realloc(ret, sizeof(int *) * hmapsize);
                    *returnColumnSizes = 
                        realloc(*returnColumnSizes, sizeof(int) * hmapsize);
                }
                ret[rsize-1] = calloc(3, sizeof(int));
                ret[rsize-1][0] = vi;
                ret[rsize-1][1] = vs;
                ret[rsize-1][2] = ve;
                (*returnColumnSizes)[rsize-1] = 3;

                tln = calloc(1, sizeof(*tln));
                if (vs > ve) {
                    tln->s = ve;
                    tln->e = vs;
                } else {
                    tln->s = vs;
                    tln->e = ve;
                }

                tln->next = hmap[vi & HASH_MASK];
                hmap[vi & HASH_MASK] = tln;
                tln = NULL;
                s++;
                continue;
            }
            if ((vi + vs + ve) > 0) {
                e--;
                continue;
            }
           if ((vi + vs + ve) < 0) {
                s++;
                continue;
            }
        }
    }
    *returnSize = rsize;
    return ret;
}

题目

LeetCode刷题笔记- 15.三数之和_第1张图片

注意点

  1. 需要去重,本文去重使用Hash的办法,如代码中hmap;
  2. 去重时注意s与e位置的值得大小排序后再进行比较;
  3. 找到结果后s,e继续保持遍历,避免漏掉场景;
  4. hash表的内存分配注意控制,每个进行分配realloc的代码存在过超时的情况;

你可能感兴趣的:(算法刷题,leetcode,算法,职场和发展,c语言)