0% found this document useful (0 votes)
14 views35 pages

A

Uploaded by

s0618614
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views35 pages

A

Uploaded by

s0618614
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

18.

4Sum
#include <stdio.h>
#include <stdlib.h>

// Function prototypes
int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes);
void printResult(int** result, int returnSize, int* returnColumnSizes);

int compare(const void *a, const void *b) {


return (*(int*)a - *(int*)b);
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) {
*returnSize = 0;
if (numsSize < 4) return NULL;

qsort(nums, numsSize, sizeof(int), compare);

// Allocate memory for the result and column sizes


int** result = malloc(1000 * sizeof(int*));
*returnColumnSizes = malloc(1000 * sizeof(int));

for (int i = 0; i < numsSize - 3; i++) {


if (i > 0 && nums[i] == nums[i - 1]) continue;

for (int j = i + 1; j < numsSize - 2; j++) {


if (j > i + 1 && nums[j] == nums[j - 1]) continue;

int left = j + 1;
int right = numsSize - 1;

while (left < right) {


long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];

if (sum == target) {
result[*returnSize] = malloc(4 * sizeof(int));
result[*returnSize][0] = nums[i];
result[*returnSize][1] = nums[j];
result[*returnSize][2] = nums[left];
result[*returnSize][3] = nums[right];
(*returnColumnSizes)[*returnSize] = 4;
(*returnSize)++;

while (left < right && nums[left] == nums[left + 1]) left++;


while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}

return result;
}
// Helper function for testing
void testFourSum() {
int nums[] = {1, 0, -1, 0, -2, 2};
int target = 0;
int numsSize = sizeof(nums) / sizeof(nums[0]);
int returnSize;
int* returnColumnSizes;

int** result = fourSum(nums, numsSize, target, &returnSize, &returnColumnSizes);


printResult(result, returnSize, returnColumnSizes);

for (int i = 0; i < returnSize; i++) {


free(result[i]);
}
free(result);
free(returnColumnSizes);
}

void printResult(int** result, int returnSize, int* returnColumnSizes) {


printf("[\n");
for (int i = 0; i < returnSize; i++) {
printf(" [");
for (int j = 0; j < returnColumnSizes[i]; j++) {
printf("%d", result[i][j]);
if (j < returnColumnSizes[i] - 1) printf(", ");
}
printf("]\n");
}
printf("]\n");
}

1007. Minimum Domino Rotations in every row.


int minDominoRotations(int* A, int ASize, int* B, int BSize){
bool a_ok, b_ok;
int i, a_up, a_down, b_down, b_up;

a_ok = b_ok = true;


a_up = a_down = b_down = b_up = 0;

for (i = 0; i < ASize; i ++) {


if (a_ok && A[i] != A[0] && B[i] != A[0]) a_ok = false;
if (b_ok && B[i] != B[0] && A[i] != B[0]) b_ok = false;

if (!a_ok && !b_ok) return -1;

if (a_ok) {
if (A[i] != A[0]) a_up ++; // flip up to make all are A[0] on top
else if (B[i] != A[0]) a_down ++; // flip down to make all are A[0] in bottom
}
if (b_ok) {
if (B[i] != B[0]) b_down ++;
else if (A[i] != B[0]) b_up ++;
}
}

if (a_ok) return a_up < a_down ? a_up : a_down;


if (b_ok) return b_up < b_down ? b_up : b_down;

return -1;
}
1004.Maximum depth of Binary Tree
int maxDepth(struct TreeNode* root) {
if (!root) return 0; // Check if the root is NULL
int l = maxDepth(root->left) + 1; // Depth of the left subtree
int r = maxDepth(root->right) + 1; // Depth of the right subtree
return l > r ? l : r; // Return the larger depth
}

105.Construct binary tree from pre order and in order traversal


typedef struct {
int *preorder;
int pre_idx;
int pre_sz;
int *inorder;
} data_t;

struct TreeNode *make_tree(data_t *data, int start, int end) {


struct TreeNode *node;
int i;

if (start == end) return NULL;

node = malloc(sizeof(struct TreeNode));


//assert(node);
node->val = data->preorder[data->pre_idx++];
i = start;
while (i < end && data->inorder[i] != node->val) i++;

node->left = make_tree(data, start, i);


node->right = make_tree(data, i + 1, end);

return node;
}

struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
data_t data;

data.preorder = preorder;
data.pre_idx = 0;
data.pre_sz = preorderSize;
data.inorder = inorder;

return make_tree(&data, 0, inorderSize);


}

106. construct binary tree from inorder and postorder traversal


typedef struct {
int *postorder;
int post_idx;
int *inorder;
} data_t;

struct TreeNode *make_tree(data_t *data, int start, int end) {


struct TreeNode *node;
int i;
if (start == end) return NULL;

node = malloc(sizeof(struct TreeNode));


//assert(node);
node->val = data->postorder[--data->post_idx];

i = start;
while (i < end && data->inorder[i] != node->val) i++;

node->right = make_tree(data, i + 1, end);


node->left = make_tree(data, start, i);

return node;
}

struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize) {
data_t data;
data.postorder = postorder;
data.post_idx = postorderSize;
data.inorder = inorder;

return make_tree(&data, 0, inorderSize);


}

108. convert sorted array to binary search tree


struct TreeNode *gen_tree(int *nums, int start, int end) {
struct TreeNode *node;
int mid;
if (start > end) return NULL;

node = malloc(sizeof(struct TreeNode));


//assert(node);

mid = start + (end - start) / 2;


node->val = nums[mid];
node->left = gen_tree(nums, start, mid - 1); // sub tree on left
node->right = gen_tree(nums, mid + 1, end); // sub tree on right

return node;
}

struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {


return gen_tree(nums, 0, numsSize - 1);
}

114. flatten binary tree to linked list


struct TreeNode *preOrderTraversal(struct TreeNode *prev, struct TreeNode *node) {
struct TreeNode *left, *right;

if (!node) return prev;

left = node->left;
right = node->right;
node->left = node->right = NULL;

prev->right = node;
prev = node;
prev = preOrderTraversal(prev, left); // it's important to update prev
prev = preOrderTraversal(prev, right);

return prev;
}

void flatten(struct TreeNode* root) {


struct TreeNode head = { 0 };
preOrderTraversal(&head, root);
}

120.Triangle
#include <stdio.h>
#include <stdlib.h>

int minimumTotal(int** triangle, int triangleRowSize, int* triangleColSizes) {


int *x;
int i, j, k;

// Handle edge case for a triangle with only one row


if (triangleRowSize == 1) return triangle[0][0];

// Allocate memory for the array to hold minimum path sums


x = malloc(triangleRowSize * sizeof(int));
if (!x) return 0; // Memory allocation failed

// Process the triangle from bottom to top


for (i = triangleRowSize - 1; i >= 0; i--) {
for (j = 0; j < triangleColSizes[i]; j++) {
if (i == triangleRowSize - 1) {
// Last row, initialize with the values directly
k = triangle[i][j];
} else {
// Update the current cell with the minimum path sum
k = triangle[i][j] + (x[j] < x[j + 1] ? x[j] : x[j + 1]);
}
x[j] = k; // Store the computed sum
}
}

// The minimum path sum will be at the top of the triangle


k = x[0]; // This should hold the final minimum path sum
free(x); // Free allocated memory
return k;
}

121.Best time to buy and sell stock


int maxProfit(int* prices, int pricesSize) {
int i, d, k = 0;

if (pricesSize < 2) return 0;

// O(n)
int cost = prices[0];
for (i = 1; i < pricesSize; i ++) {
if (prices[i] > cost) {
d = prices[i] - cost;
k = d > k ? d : k;
} else {
cost = prices[i];
}
}

return k;
}

122.Best time to buy and sell stock II


int maxProfit(int* prices, int pricesSize) {
int i, d, p;

if (pricesSize < 2) return 0;

p = 0;
for (i = 1; i < pricesSize; i ++) {
d = prices[i] - prices[i - 1];
p = d > 0 ? p + d : p; // get it as long as it is a profit!
}

return p;
}

123.Best time to buy and sell stock III


int maxProfit(int* prices, int pricesSize) {
int buy1, buy2; // max profit if I buy
int sell1, sell2; // max profit if I sell
int i;

buy1 = buy2 = 0x80000000; // min of integer


sell1 = sell2 = 0;

for (i = 0; i < pricesSize; i ++) {


// possible profit
buy1 = buy1 > 0 - prices[i] ? buy1 : 0 - prices[i];
sell1 = sell1 > buy1 + prices[i] ? sell1 : buy1 + prices[i];
buy2 = buy2 > sell1 - prices[i] ? buy2 : sell1 - prices[i];
sell2 = sell2 > buy2 + prices[i] ? sell2 : buy2 + prices[i];
}

return sell2;
}

124.Binary tree maximum path sum


int maxsum(struct TreeNode *node, int *max) {
int l, r, k, s;

if (!node) return 0;

l = maxsum(node->left, max);
r = maxsum(node->right, max);

l = l > 0 ? l : 0; // ignore negative


r = r > 0 ? r : 0;

s = node->val + l + r; // current node + both sides


if (*max < s) *max = s;

k = node->val + (l > r ? l : r); // current node + one side only


return k;
}
int maxPathSum(struct TreeNode* root) {
int max;
if (root) {
max = root->val;
maxsum(root, &max);
} else {
max = 0;
}
return max;
}

125.Valid Palindrome
#include <stdbool.h>
#include <string.h>

bool isPalindrome(char* s) {
int i = 0;
int j;
char a, b;

if (!s || !*s) return true;

j = strlen(s) - 1;
while (i < j) {
a = s[i];
b = s[j];

// Skip non-alphanumeric characters from the front


if (!((a >= '0' && a <= '9') || (a >= 'A' && a <= 'Z') || (a >= 'a' && a <= 'z'))) {
i++;
continue;
}
// Skip non-alphanumeric characters from the back
if (!((b >= '0' && b <= '9') || (b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z'))) {
j--;
continue;
}

// Convert to uppercase for comparison


a = (a >= 'a') ? a - 'a' + 'A' : a;
b = (b >= 'a') ? b - 'a' + 'A' : b;

if (a != b) {
return false; // Not a palindrome
}

i++;
j--;
}
return true; // Is a palindrome
}

127.Word ladder
typedef struct {
char **q;
int n;
} q_t;
int one_diff(char *a, char *b) {
int diff = 0;
while (*a && diff <= 1) {
diff += (*a != *b) ? 1 : 0;
a ++; b ++;
}
return diff == 1 ? 1 : 0;
}
int bfs(q_t *q1, q_t *q2, char *end, char **dict, int sz, int *v) {
int i, d;
char *a, *b;
q_t *tmp;

d = 1;
while (q1->n) {
while (q1->n) {
a = q1->q[-- q1->n];
for (i = 0; i < sz; i ++) {
if (v[i]) continue;
b = dict[i];
if (one_diff(a, b)) {
if (!strcmp(b, end)) { // done!
return d;
}
v[i] = 1;
q2->q[q2->n ++] = b;
}
}
}
tmp = q1; // switch queues
q1 = q2;
q2 = tmp;
d ++;
}

return -1;
}
int ladderLength(char* beginWord, char* endWord, char** wordList, int wordListSize) {
int *visited, i, n = 0;
q_t q1 = { 0 }, q2 = { 0 };

visited = calloc(wordListSize, sizeof(int));


q1.q = malloc(wordListSize * 2 * sizeof(char *));
//assert(visited && q1);
q2.q = &q1.q[wordListSize];

q1.q[q1.n ++] = beginWord; // initialize q1

n = bfs(&q1, &q2, endWord, wordList, wordListSize, visited);

free(visited);
free(q1.q);

return n + 1;
}

132.Palindrome Partioning II
int _min(int a, int b) {
return a < b ? a : b;
}
int minCut(char* s) {
int *dp, n, i, k;
n = strlen(s);

dp = malloc((n + 1) * sizeof(int)); // number of cuts on length


//assert(dp);

dp[0] = -1;
for (i = 0; i < n; i ++) {
dp[i + 1] = dp[i] + 1;
}

for (i = 0; i < n; i ++) {


dp[i + 1] = _min(dp[i + 1], dp[i] + 1);

for (k = 1; // "aba"
i - k >= 0 &&
i + k < n &&
s[i - k] == s[i + k];
k ++) {
dp[i + k + 1] = _min(dp[i + k + 1], dp[i - k] + 1);
}

for (k = 1; // "aaaa"
i - k + 1 >= 0 &&
i + k < n &&
s[i - k + 1] == s[i + k];
k ++) {
dp[i + k + 1] = _min(dp[i + k + 1], dp[i - k + 1] + 1);
}
}
i = dp[n];

free(dp);

return i;
}

135.Candy
int candy(int* ratings, int ratingsSize) {
int *candies;
int i, x;

if (ratingsSize < 2) return ratingsSize;

candies = malloc(ratingsSize * sizeof(int));


//assert(candies);

candies[0] = 1;
for (i = 1; i < ratingsSize; i ++) {
if (ratings[i] > ratings[i - 1]) {
candies[i] = candies[i - 1] + 1;
} else {
candies[i] = 1;
}
}

x = candies[ratingsSize - 1];

for (i = ratingsSize - 2; i >= 0; i --) {


if (ratings[i] > ratings[i + 1]) {
if (candies[i] <= candies[i + 1]) {
candies[i] = candies[i + 1] + 1;
}
}
x += candies[i];
}
free(candies);

return x;
}

136.Single Number
int singleNumber(int* nums, int numsSize) {
int i, k = 0;
for (i = 0; i < numsSize; i++) {
k = k ^ nums[i]; // a ^ a equals to 0; 0 ^ a equals to a
}
return k;
}

137.Single Number I
int singleNumber(int* nums, int numsSize) {
int i, ones, twos;
ones = twos = 0;
for (i = 0; i < numsSize; i++) {
ones = (ones ^ nums[i]) & ~twos;
twos = (twos ^ nums[i]) & ~ones;
}
return ones;
}
139.Word Break
bool search(char *s, int l, char **wordDict, int wordDictSize) {
int i;
char *word;
for (i = 0; i < wordDictSize; i ++) {
word = wordDict[i];
if (word && l == strlen(word) && !strncmp(s, word, l)) return true;
}
return false;
}
bool wordBreak(char* s, char** wordDict, int wordDictSize) {
int i, j, l;
bool *buff, *e, result;

l = strlen(s);

buff = calloc((l + 1), sizeof(bool));


//assert(buff);

buff[0] = true;
e = &buff[1];

for (i = 0; i < l; i ++) {


for (j = i; !e[i] && j >= 0; j --) {
e[i] = e[j - 1] && search(&s[j], i - j + 1, wordDict, wordDictSize);
}
}

result = e[l - 1];


free(buff);

return result;
}

140.Word Break II
#include <stdlib.h>
#include <string.h>

typedef struct {
char **p;
int sz;
int n;
} res_t;

typedef struct {
char *b;
int sz;
int n;
} buff_t;

void add2res(res_t *res, char *str) {


if (res->sz == res->n) {
res->sz *= 2;
res->p = realloc(res->p, res->sz * sizeof(char *));
// assert(res->p);
}
res->p[res->n++] = str;
}
void add2buff(buff_t *buff, int n, char *s, int l) {
buff->n = n;
if (buff->sz <= buff->n + l + 2) {
buff->sz = buff->sz * 2 + l + 2;
buff->b = realloc(buff->b, buff->sz * sizeof(char));
// assert(buff->b);
}
strncpy(&buff->b[buff->n], s, l);
buff->n += l;
buff->b[buff->n] = ' ';
buff->n++;
}

int *newvec() {
int *vec = malloc(12 * sizeof(int));
// assert(vec);
vec[0] = 12;
vec[1] = 0;
return vec;
}

void add2vec(int *vec, int i) {


if (vec[0] == vec[1]) {
vec[0] *= 2;
vec = realloc(vec, vec[0] * sizeof(int));
// assert(vec);
}
vec[2 + vec[1]++] = i;
}
void bt(res_t *res, buff_t *buff, char *s, int **dp, int start, int end) {
int i, k, n, *vec;

if (start == end) {
buff->b[--buff->n] = 0;
add2res(res, strdup(buff->b));
return;
}

n = buff->n;

vec = dp[start];
for (i = 0; i < vec[1]; i++) {
k = vec[2 + i];
add2buff(buff, n, &s[start], k - start);
bt(res, buff, s, dp, k, end);
}
}

char** wordBreak(char* s, char** wordDict, int wordDictSize, int* returnSize) {


res_t res;
buff_t buff;

int *wsz, **dp, *vec;


int len, i, j, k;

res.sz = 10;
res.n = 0;
res.p = malloc(res.sz * sizeof(char *));
// assert(res.p);

wsz = calloc(wordDictSize, sizeof(int));


len = strlen(s);
dp = calloc(len + 1, sizeof(int *));
// assert(dp && used && len);

buff.sz = 100;
buff.n = 0;
buff.b = malloc(buff.sz * sizeof(char));
// assert(buff.b);

for (i = 0; i < wordDictSize; i++) {


wsz[i] = strlen(wordDict[i]);
}

dp[0] = newvec();
for (i = 0; i < len; i++) {
if (dp[i]) { // a valid point to cut
for (j = 0; j < wordDictSize; j++) {
if (!strncmp(&s[i], wordDict[j], wsz[j])) {
k = i + wsz[j];
add2vec(dp[i], k);
if (!dp[k]) dp[k] = newvec();
}
}
}
}
if (dp[len]) {
bt(&res, &buff, s, dp, 0, len);
}

free(wsz);
for (i = 1; i <= len; i++) {
if (dp[i]) free(dp[i]);
}
free(dp);
free(buff.b);

*returnSize = res.n;

return res.p;
}

148.Sort List
struct ListNode* divide(struct ListNode *p) {
struct ListNode *a, *b;
a = p;
b = p->next;

while (b) {
b = b->next; // b moves two steps
if (b) {
a = a->next; // a moves one steps
b = b->next;
}
}
b = a->next; // this is the middle point
a->next = NULL;

return b;
}

struct ListNode* merge(struct ListNode *a, struct ListNode *b) {


struct ListNode head, *p, *c;

p = &head;

while (a && b) {
if (a->val < b->val) {
c = a;
a = a->next;
} else {
c = b;
b = b->next;
}
p->next = c;
p = c;
}

p->next = a ? a : b;

return head.next;
}
struct ListNode* sortList(struct ListNode* head) {
struct ListNode *p, *a, *b;

if (!head || !head->next) return head;

p = divide(head); // divide the list to two

a = sortList(head); // sort separately


b = sortList(p);

p = merge(a, b); // and merge them

return p;
}

152.Maximum Product Subarray


int maxProduct(int* nums, int numsSize) {
int i, j, k, m;
#if 0
// O(n2)
for (i = 0; i < numsSize; i++) {
k = nums[i];
if (i == 0 || m < k) m = k;
for (j = i + 1; j < numsSize; j++) {
k = k * nums[j];
if (m < k) m = k;
}
}
#else
int min, max;
m = min = max = nums[0];
for (i = 1; i < numsSize; i++) {
if (nums[i] >= 0) {
k = max * nums[i];
max = k > nums[i] ? k : nums[i];
k = min * nums[i];
min = k < nums[i] ? k : nums[i];
} else {
j = max;
k = min * nums[i];
max = k > nums[i] ? k : nums[i];
k = j * nums[i];
min = k < nums[i] ? k : nums[i];
}
m = m > max ? m : max;
}
#endif
return m;
}

162.Find Peak element


int findPeakElement(int* nums, int numsSize) {
#if 0
int i;

for (i = 1; i < numsSize && nums[i] > nums[i - 1]; i++) {


}

return i - 1;
#else
int l, r, m;
if (numsSize == 1) return 0;

l = 0;
r = numsSize - 1;
while (l < r) {
m = l + (r - l) / 2;
if (nums[m] < nums[m + 1]) {
l = m + 1;
} else {
r = m;
}
}

return l;
#endif
}

165.Compare version numbers


int compareVersion(char* version1, char* version2) {
int a, b;
char *v1, *v2;

while (version1 || version2) {


if (version1) {
v1 = version1;
version1 = strchr(version1, '.');
if (version1) {
*version1 = 0; // Terminate the string at the dot
version1++; // Move to the next character after the dot
}
a = atoi(v1);
} else {
a = 0;
}

if (version2) {
v2 = version2;
version2 = strchr(version2, '.');
if (version2) {
*version2 = 0; // Terminate the string at the dot
version2++; // Move to the next character after the dot
}
b = atoi(v2);
} else {
b = 0;
}

if (a > b) return 1;
if (a < b) return -1;
}

return 0;
}

166. fraction to recurring decimal


#include <stdio.h>
#include <stdlib.h>

char* fractionToDecimal(int numerator, int denominator) {


char *p;
int psz, n, *dec, dsz, x;
long long num, den, k, f;
int i, repeat_at;
int neg = 0;

psz = dsz = 100; n = x = 0;


p = malloc(psz * sizeof(char));
//assert(p);

neg = ((numerator > 0 && denominator < 0) ||


(numerator < 0 && denominator > 0)) ? 1 : 0;
num = numerator;
den = denominator;
num = (num < 0) ? -num : num;
den = (den < 0) ? -den : den;

k = num / den;
f = num % den;

if (neg && (k || f)) p[n++] = '-';

n += sprintf(&p[n], "%lld", k);


if (!f) {
p[n] = 0;
return p;
}

p[n++] = '.';
dec = malloc(dsz * sizeof(int));
//assert(dec);

repeat_at = -1;
if (f < 0) f = -f;
while (f) {
for (i = 0; i < x; i += 2) {
if (dec[i] == f) {
repeat_at = i;
goto done;
}
}
if (x + 1 >= dsz) {
dsz *= 2;
dec = realloc(dec, dsz * sizeof(int));
//assert(dec);
}
dec[x++] = f;
f *= 10;
k = f / den;
dec[x++] = k;
f = f % den;
}

done:
for (i = 0; i < x; i += 2) {
if (n + 3 > psz) {
psz *= 2;
p = realloc(p, psz * sizeof(char));
//assert(p);
}
if (repeat_at == i) {
p[n++] = '(';
}
p[n++] = '0' + dec[i + 1];
}
if (repeat_at != -1) p[n++] = ')';
p[n++] = 0;

free(dec);

return p;
}

167. two sum ii input array is sorted


#include <stdio.h>
#include <stdlib.h>

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {


int *result;
int i, j, total;

result = malloc(2 * sizeof(int));


// assert(result); // Uncomment this line for safety checks

*returnSize = 0;

i = 0;
j = numbersSize - 1;
while (i < j) {
total = numbers[i] + numbers[j];
if (total > target) {
j--;
} else if (total < target) {
i++;
} else {
result[0] = i + 1; // Store the first index (1-based)
result[1] = j + 1; // Store the second index (1-based)
*returnSize = 2; // Indicate that we found a result
break;
}
}

return result; // Return the result array


}

You might also like