Skip to content

Commit 4d90c4f

Browse files
committed
Add 0128-longest-consecutive-sequence.c
1 parent a651870 commit 4d90c4f

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

c/0128-longest-consecutive-sequence.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#define INIT_HASH_SIZE 4096
2+
3+
// Represent an element in a hash table.
4+
typedef struct Hash {
5+
int key;
6+
struct Hash *next;
7+
} Hash;
8+
9+
Hash **InitHash() {
10+
Hash **h = (Hash**)calloc(INIT_HASH_SIZE, sizeof(Hash*));
11+
assert(h);
12+
return h;
13+
}
14+
15+
Hash *NewHash(int key) {
16+
Hash *h = (Hash*)malloc(sizeof(Hash));
17+
assert(h);
18+
h->key = key;
19+
h->next = NULL;
20+
return h;
21+
}
22+
23+
int HashKey(int key) {
24+
while(key < 0) key += INIT_HASH_SIZE;
25+
return (key % INIT_HASH_SIZE);
26+
}
27+
28+
void AddHash(Hash **hash, int key) {
29+
assert(hash);
30+
int hash_key = HashKey(key);
31+
Hash **head = hash + hash_key;
32+
if (!*head) {
33+
*head = NewHash(key);
34+
} else {
35+
Hash *h = *head;
36+
while (h) {
37+
if (h->key == key) {
38+
return;
39+
} else if (!h->next) {
40+
h->next = NewHash(key);
41+
return;
42+
}
43+
h = h->next;
44+
}
45+
}
46+
}
47+
48+
// If hash not round return 0 on purpose.
49+
int GetHash(Hash **hash, int key) {
50+
assert(hash);
51+
Hash * h = hash[HashKey(key)];
52+
while(h) {
53+
if (h->key == key) {
54+
return 1;
55+
}
56+
h = h->next;
57+
}
58+
59+
return 0;
60+
}
61+
62+
int longestConsecutive(int* nums, int numsSize){
63+
Hash **hash = InitHash();
64+
int i, len, n, maxLen = 0;
65+
66+
for (i = 0; i < numsSize; i++) {
67+
AddHash(hash, nums[i]);
68+
}
69+
for (i = 0; i < numsSize; i++) {
70+
n = nums[i];
71+
len = 1;
72+
if (GetHash(hash, n - 1) == 0) {
73+
while(GetHash(hash, ++n) == 1) {
74+
len++;
75+
}
76+
}
77+
maxLen = (len > maxLen) ? len : maxLen;
78+
}
79+
80+
return maxLen;
81+
}
82+
83+
//
84+
// According to the official solution, using hash map will be considered as O(n).
85+
//
86+
// Alternative solution 1 - With uthash, the runtime is poorer. It is a little surprise.
87+
//
88+
// typedef struct Hash {
89+
// int num;
90+
// UT_hash_handle hh;
91+
// } Hash;
92+
//
93+
// void AddHash(Hash **hash, int num) {
94+
// Hash *entry;
95+
// HASH_FIND_INT(*hash, &num, entry);
96+
// if (!entry) {
97+
// entry = malloc(sizeof(Hash));
98+
// entry->num = num;
99+
// HASH_ADD_INT(*hash, num, entry);
100+
// }
101+
// }
102+
//
103+
// Hash * GetHash(Hash **hash, int num) {
104+
// Hash *entry = NULL;
105+
// HASH_FIND_INT(*hash, &num, entry);
106+
// return entry;
107+
// }
108+
//
109+
// int longestConsecutive(int* nums, int numsSize){
110+
// Hash *root = NULL;
111+
// int i, len, n, maxLen = 0;
112+
//
113+
// for (i = 0; i < numsSize; i++) {
114+
// AddHash(&root, nums[i]);
115+
// }
116+
// for (i = 0; i < numsSize; i++) {
117+
// n = nums[i];
118+
// len = 1;
119+
// if (!GetHash(&root, n - 1)) {
120+
// while(GetHash(&root, ++n)) {
121+
// len++;
122+
// }
123+
// }
124+
// maxLen = (len > maxLen) ? len : maxLen;
125+
// }
126+
//
127+
// return maxLen;
128+
// }
129+
//
130+
//
131+
// Alternative solution 2 - With sorting, O(nlogn), the runtime is the best.
132+
//
133+
// int compare(const void *a, const void *b) {
134+
// return *(int*)a - *(int*)b;
135+
// }
136+
//
137+
// int longestConsecutive(int* nums, int numsSize){
138+
// int i, len, max;
139+
// if (numsSize <= 0) {
140+
// return 0;
141+
// }
142+
// len = 1;
143+
// max = 1;
144+
// qsort(nums, numsSize, sizeof(int), compare);
145+
// for (i = 0; i < numsSize - 1; i++) {
146+
// if (nums[i] + 1 == nums[i + 1]) {
147+
// len++;
148+
// } else if (nums[i] == nums[i + 1]){
149+
// continue;
150+
// } else {
151+
// len = 1;
152+
// }
153+
// max = (max > len) ? max : len;
154+
// }
155+
//
156+
// return max;
157+
// }
158+
//

0 commit comments

Comments
 (0)