Skip to content

Commit

Permalink
Improvement
Browse files Browse the repository at this point in the history
Signed-off-by: begeekmyfriend <[email protected]>
  • Loading branch information
begeekmyfriend committed Sep 1, 2017
1 parent eebb0bd commit 92dc38b
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 394 deletions.
147 changes: 37 additions & 110 deletions 001_two_sum/two_sum.c
Original file line number Diff line number Diff line change
@@ -1,125 +1,51 @@
#include <stdio.h>
#include <stdlib.h>

struct hlist_node;

struct hlist_head {
struct hlist_node *first;
};

struct hlist_node {
struct hlist_node *next, **pprev;
};

static inline void INIT_HLIST_HEAD(struct hlist_head *h) {
h->first = NULL;
}

static inline void INIT_HLIST_NODE(struct hlist_node *n) {
n->next = NULL;
n->pprev = NULL;
}

static inline int hlist_empty(struct hlist_head *h) {
return !h->first;
}

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
static void bubble_sort(int *nums, int *indexes, int size)
{
if (h->first != NULL) {
h->first->pprev = &n->next;
}
n->next = h->first;
n->pprev = &h->first;
h->first = n;
}

static inline void hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next != NULL) {
next->pprev = pprev;
int i, flag = size;
while (flag > 0) {
int len = flag;
flag = 0;
for (i = 1; i < len; i++) {
if (nums[i] < nums[i - 1]) {
int tmp = nums[i];
nums[i] = nums[i - 1];
nums[i - 1] = tmp;
tmp = indexes[i];
indexes[i] = indexes[i - 1];
indexes[i - 1] = tmp;
flag = i;
}
}
}
}

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))

#define hlist_entry(ptr, type, member) \
container_of(ptr, type, member)

#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos; pos = pos->next)

#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n)

static int * twosum(int *nums, int numsSize, int target)
{
struct hash_table {
struct hlist_head head;
};
struct plus_elem {
int index;
int num;
struct hlist_node node;
};

if (numSize < 2) {
return NULL;
}

int i, j;
struct hash_table *ht = malloc(numsSize * sizeof(*ht));
for (i = 0; i < numsSize; i++) {
INIT_HLIST_HEAD(&ht[i].head);
}

struct plus_elem *elems = malloc(numsSize * sizeof(*elems));
for (i = 0; i < numsSize; i++) {
elems[i].num = 0;
INIT_HLIST_NODE(&elems[i].node);
}

int *indexes = malloc(numsSize * sizeof(int));
for (i = 0; i < numsSize; i++) {
int num = nums[i] < 0 ? -nums[i] : nums[i];
int hash = num % numsSize;
elems[i].index = i;
elems[i].num = nums[i];
hlist_add_head(&elems[i].node, &ht[hash].head);
indexes[i] = i;
}

for (i = 0; i < numsSize; i++) {
int other = target - nums[i];
int h1 = nums[i] < 0 ? -nums[i] % numsSize : nums[i] % numsSize;
int hash = other < 0 ? -other % numsSize : other % numsSize;
int index = -1;
struct hlist_node *pos;

hlist_for_each(pos, &ht[hash].head) {
struct plus_elem *elem = hlist_entry(pos, struct plus_elem, node);
if (elem->num == other) {
/* Eliminate duplicate */
if (elem->index > i) {
index = elem->index;
break;
}
}
}

if (index >= 0) {
int *indexes = malloc(2 * sizeof(int));
if (indexes == NULL) {
break;
}
indexes[0] = i < index ? i : index;
indexes[1] = i > index ? i : index;
return indexes;
bubble_sort(nums, indexes, numsSize);

int count = 0;
int *results = malloc(2 * sizeof(int));
i = 0;
j = numsSize - 1;
while (i < j) {
int diff = target - nums[i];
if (diff > nums[j]) {
while (++i < j && nums[i] == nums[i - 1]) {}
} else if (diff < nums[j]) {
while (--j > i && nums[j] == nums[j + 1]) {}
} else {
results[0] = indexes[i];
results[1] = indexes[j];
return results;
}
}

return NULL;
}

Expand All @@ -129,9 +55,10 @@ int main(void)
//int target = -8;
//int nums[] = {0,4,3,0};
//int target = 0;
int nums[] = { 3, 2, 4 };
int nums[] = { 3, 2, 3 };
int count = sizeof(nums) / sizeof(*nums);
int target = 6;
int *indexes = twosum(nums, sizeof(nums) / sizeof(nums[0]), target);
int *indexes = twosum(nums, count, target);
if (indexes != NULL) {
printf("%d %d\n", indexes[0], indexes[1]);
} else {
Expand Down
160 changes: 31 additions & 129 deletions 015_three_sum/three_sum.c
Original file line number Diff line number Diff line change
@@ -1,154 +1,55 @@
#include <stdio.h>
#include <stdlib.h>

struct hlist_node;

struct hlist_head {
struct hlist_node *first;
};

struct hlist_node {
struct hlist_node *next, **pprev;
};

static inline void INIT_HLIST_HEAD(struct hlist_head *h) {
h->first = NULL;
}

static inline void INIT_HLIST_NODE(struct hlist_node *n) {
n->next = NULL;
n->pprev = NULL;
}

static inline int hlist_empty(struct hlist_head *h) {
return !h->first;
}

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
static void insert_sort(int *nums, int len)
{
if (h->first != NULL) {
h->first->pprev = &n->next;
int i, j;
for (i = 1; i < len; i++) {
int tmp = nums[i];
for (j = i - 1; j >= 0 && nums[j] > tmp; j--) {
nums[j + 1] = nums[j];
}
nums[j + 1] = tmp;
}
n->next = h->first;
n->pprev = &h->first;
h->first = n;
}

static inline void hlist_del(struct hlist_node *n)
static void two_sum(int *nums, int low, int high, int target, int **results, int *count)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next != NULL) {
next->pprev = pprev;
}
}

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))

#define hlist_entry(ptr, type, member) \
container_of(ptr, type, member)

#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos; pos = pos->next)

#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n)

static int exist(int **triplets, int count, int *t)
{
int i;
for (i = 0; i < count; i++) {
int *triplet = triplets[i];
if ((triplet[0] == t[0] && triplet[1] == t[1] && triplet[2] == t[2]) ||
(triplet[0] == t[0] && triplet[1] == t[2] && triplet[2] == t[1]) ||
(triplet[0] == t[1] && triplet[1] == t[0] && triplet[2] == t[2]) ||
(triplet[0] == t[1] && triplet[1] == t[2] && triplet[2] == t[0]) ||
(triplet[0] == t[2] && triplet[1] == t[0] && triplet[2] == t[1]) ||
(triplet[0] == t[2] && triplet[1] == t[1] && triplet[2] == t[0])) {
return 1;
while (low < high) {
int diff = target - nums[low];
if (diff > nums[high]) {
while (++low < high && nums[low] == nums[low - 1]) {}
} else if (diff < nums[high]) {
while (--high > low && nums[high] == nums[high + 1]) {}
} else {
results[*count] = malloc(3 * sizeof(int));
results[*count][0] = -target;
results[*count][1] = nums[low];
results[*count][2] = nums[high];
(*count)++;
while (++low < high && nums[low] == nums[low - 1]) {}
while (--high > low && nums[high] == nums[high + 1]) {}
}
}
return 0;
}

/**
** Return an array of arrays of size *returnSize.
** Note: The returned array must be malloced, assume caller calls free().
**/
static int** threeSum(int* nums, int numsSize, int* returnSize) {
struct hash_table {
struct hlist_head head;
};
struct plus_elem {
int index;
int num;
struct hlist_node node;
};

if (numsSize < 3) {
return NULL;
}
insert_sort(nums, numsSize);

int i, j, count = 0, cap = 1;
int **results = malloc(cap * sizeof(int *));
struct hash_table *ht = malloc(numsSize * sizeof(*ht));
for (i = 0; i < numsSize; i++) {
INIT_HLIST_HEAD(&ht[i].head);
}

struct plus_elem *elems = malloc(numsSize * sizeof(*elems));
for (i = 0; i < numsSize; i++) {
elems[i].num = 0;
INIT_HLIST_NODE(&elems[i].node);
}

for (i = 0; i < numsSize; i++) {
int num = nums[i] < 0 ? -nums[i] : nums[i];
int hash = num % numsSize;
elems[i].index = i;
elems[i].num = nums[i];
hlist_add_head(&elems[i].node, &ht[hash].head);
}

int i, j, count = 0, capacity = 50000;
int **results = malloc(capacity * sizeof(int *));
for (i = 0; i < numsSize; i++) {
int target = -nums[i];
for (j = i + 1; j < numsSize; j++) {
int other = target - nums[j];
int hash = other < 0 ? -other % numsSize : other % numsSize;
int index = -1;
struct hlist_node *pos;

hlist_for_each(pos, &ht[hash].head) {
struct plus_elem *elem = hlist_entry(pos, struct plus_elem, node);
if (elem->num == other) {
/* Eliminate duplicate */
if (elem->index > j) {
index = elem->index;
break;
}
}
}

if (index >= 0) {
int *triplet = malloc(3 * sizeof(int));
triplet[0] = nums[i];
triplet[1] = nums[j];
triplet[2] = nums[index];
if (!exist(results, count, triplet)) {
if (count + 1 >= cap) {
cap *= 2;
results = realloc(results, cap * sizeof(int *));
}
results[count++] = triplet;
} else {
free(triplet);
}
}
if (i == 0 || i > 0 && nums[i] != nums[i - 1]) {
two_sum(nums, i + 1, numsSize - 1, -nums[i], results, &count);
}
}

*returnSize = count;
return results;
}
Expand All @@ -157,9 +58,10 @@ int main(void)
{
int i, count;
//int nums[] = { -1, 0, 1, 2, -1, -4 };
int nums[] = { 0, 0, 0 };
//int nums[] = { 0, 0, 0 };
//int nums[] = { -1, 0, 1, 0 };
int **triplets = threeSum(nums, sizeof(nums) / sizeof(nums[0]), &count);
int nums[] = {-2,0,0,2,2};
int **triplets = threeSum(nums, sizeof(nums) / sizeof(*nums), &count);
for (i = 0; i < count; i++) {
printf("%d %d %d\n", triplets[i][0], triplets[i][1], triplets[i][2]);
}
Expand Down
Loading

0 comments on commit 92dc38b

Please sign in to comment.