1. 程式人生 > >leetcode 第三週 c

leetcode 第三週 c

27. Remove Element

Description:

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

思路:

找到相同的,則從他後面找不同的,然後交換,直到遍歷完成。

void swap(int *a, int *b)
{
    if(a == b){
        return;
    }
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
    return;
}


int removeElement(int* nums, int numsSize, int val) {
    if(NULL == nums || 0 == numsSize){
        return 0;
    }
    int i, j;
    
    for(i = 0; i < numsSize; i++){
        if(nums[i] != val){
            continue;
        }
        for(j = i+1; j < numsSize; j++){
            if(nums[i] != nums[j]){
                swap(&nums[i], &nums[j]);
                break;
            }
        }
        if(j == numsSize){
            return i;
        }
    }
    return numsSize;
}

204. Count Primes

Description:

Count the number of prime numbers less than a non-negative number, n. 思路:

  1. 暴力整除法,即除以小於輸入值n的數,進行整除,然後輸出,超時。
  2. 對整除的數進行優化,即呼叫sqrt(),依然是超時。
  3. 填充法,既然能被整除,可以先將這些數填充,那麼餘下來就是沒法整除的質數了,可行。

最佳思路:對第三種進行優化,超過sqrt()的數是不會被整除了,也就沒必要進行填充了。

/*
int countPrimes(int n) {
    int i, j;
    int count = 0;
    
    for(i = 2; i < n; i++){
        for(j = 2; j < sqrt(i); j++){
            if(0 == i % j){
                break;
            }
        }
        if(j > sqrt(i)){
            count++;
        }
    }
    return count;
}
*/




/*
int countPrimes(int n) {
    int i, j;
    int count = 0;
    int *p_nums = malloc(sizeof(int) * n);
    
    if(p_nums){
        memset(p_nums, 0, sizeof(int) * n);
        for(i = 2; i < n; i++){
            for(j = 2; i*j<n; j++){
                p_nums[i*j] = 1;
            }
            if(0 == p_nums[i]){
                count++;
            } 
        }
        free(p_nums);
    }
    
    return count;
}
*/


int countPrimes(int n) {
    uint8_t *sieve = calloc(n, sizeof(uint8_t));
    int i, j, ret = 1;
    
    if (n <= 2)
        return 0;
    
    for (i = 3; i < sqrt(n); i += 2) {
        if (sieve[i])
            continue;
        
        for (j = i*i; j < n; j += 2*i){
            sieve[j] = 1;
        }
    }
    
    for (i = 3; i < n; i += 2)
        if (!sieve[i]){
            ret++;
        }
    
    return ret;
}

720. Longest Word in Dictionary

Description:

Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order.

If there is no answer, return the empty string.

思路:

比較特殊的一點是words是從第一個開始的,建立一顆樹,root是個虛擬點,接下來的子節點就是長度為1的字串,接下來就是分別對應的長度為2的字串,然後遍歷,找到最長的單詞,這裡利用遞迴儲存字串資訊。這裡要求返回字典序,所以首先呼叫了快排,進行了排序。執行時間感人!!

最佳思路:

       直接暴力的建立一顆多叉樹,然後進行尋找。

/*
static int cmp_function(const void *p1, const void *p2)
{
    return strcmp(* (char * const *) p1, * (char * const *) p2);
}

int longest_word(char** words, int wordsSize, char *match, int depth, int max, int cur, int start, int *max_index){
    int i;
    int index = *max_index;
    
    cur = strlen(words[index]);
    max = cur;
    for(i = start; i < wordsSize; i++){
        if(strlen(words[i]) != depth+1){
            continue;
        }
        if(0 == depth){
            cur = longest_word(words, wordsSize, words[i], depth+1, max, i, i+1, &index);
            if(cur> max){
                max = cur;
                *max_index = index;
            }
        }else{
            if(0 == memcmp(words[i], match, depth)){
                index = i;
                cur = longest_word(words, wordsSize, words[i], depth+1, max, i, i+1, &index);
                if(cur > max){
                    max = cur;
                    *max_index = index;
                }
            }
        }
    }
    return max;
}

char* longestWord(char** words, int wordsSize) {
    int max_index = 0;
    qsort(words, wordsSize, sizeof(char *), cmp_function);
    
    longest_word(words, wordsSize, NULL, 0, 0, 0, 0, &max_index);
    return words[max_index];
}

*/

typedef struct TrieNode
{
//  char c;
  bool end;
  struct TrieNode *children[26];  
}TrieNode;

static TrieNode head = {true, {NULL}};

void addTrieNode(TrieNode *head, char *s)
{
    TrieNode *top = head;
    int i = 0;
    // h = NULL
    // app -> Trie (a->p->p). head[*s - 'a'] = Trie;
//    printf("adding %s to trie\n", s);
    while(s[i] != '\0')
    {
        if((top->children[s[i] - 'a'] == NULL))
        {
            TrieNode *cur = (TrieNode *)malloc(sizeof(TrieNode));
            cur->end = false;
            if(s[i+1] == '\0') cur->end = true;
//            cur->c = s[i];
            memset(cur->children, NULL, sizeof(cur->children));
//            printf("Adding Node:%c to %c\n", cur->c, top->c);
            top->children[s[i] - 'a'] = cur;
        }
        else
        {
            if(s[i+1] == '\0') 
            {
                top->children[s[i] - 'a']->end = true;
            }
        }
        top = top->children[s[i] - 'a'];
        i++;
    }
}
void freeTrie(TrieNode *t)
{
    TrieNode *cur = t;
    int i = 0;
    if(t == NULL) return;
    for(i = 0; i < 26; i++)
    {
        if(cur->children[i] != NULL)
            freeTrie(cur->children[i]);
    }
    free(cur);
    cur = NULL;
}

int findLongest(TrieNode *t, char *lng, int *len)
{
    char *curLong[32] = {0};
    int i = 0;
    int maxLen = *len;
    if(t == NULL) return 0;
    strcpy(curLong, lng);
    for(i = 0; i < 26; i++)
    {
        
        if(t->children[i] != NULL && t->children[i]->end) 
        {
            int curLen = *len;
            lng[curLen] = i+'a';
            curLen++;
            lng[curLen] = '\0';
//            printf("findLongest: lng=%s, len=%d\n", lng, curLen);
            curLen = findLongest(t->children[i], lng, &curLen);
            if(curLen > maxLen) 
            {
                strcpy(curLong, lng);
                maxLen = curLen;
            }
        }
    }
    strcpy(lng, curLong);
    return maxLen;
}
char* longestWord(char** words, int wordsSize) {
    char *lng = (char *)malloc(32);
    memset(lng, 0, 32);
    int i = 0;
    int len = 0;
    TrieNode *head = (TrieNode *)malloc(sizeof(TrieNode));
    head->end = true;
    memset(head->children, NULL, sizeof(head->children));
    
    for(i = 0; i < wordsSize; i++)
    {
        addTrieNode(head, words[i]);
    }
    findLongest(head, lng, &len);
    freeTrie(head);
    return lng;
}

136. Single Number

Description:

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

思路:

快速排序,然後一對一對進行對比,找出單個的那個,要注意一種情況,即單個在最後一個。

int cmp_func(const void *p1, const void *p2)
{
    return *((int *)p1)-*((int *)p2);
}

int singleNumber(int* nums, int numsSize) {
    qsort(nums, numsSize, sizeof(int), cmp_func);
    int i;
    for(i = 0; i < numsSize-1; i++){
        if(nums[i] != nums[i+1]){
            return nums[i];
        }
        i++;
    }
    return nums[numsSize-1];
}

501. Find Mode in Binary Search Tree

Description:

Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST.

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than or equal to the node's key.

The right subtree of a node contains only nodes with keys greater than or equal to the node's key.

Both the left and right subtrees must also be binary search trees.

思路:

中序遍歷binary search tree,得到一個升序列,然後構造佇列,比較更新佇列。

最佳思路:

       前面一致,不過這個是直接使用了陣列,不會多次涉及記憶體申請。

* Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */


/*
struct list{
    int val;
    struct list *next;
};


struct root_info{
    int cur_count;    
    int max_count;
    int num;
    struct list *head;
};

struct root_info g_root_info = {0, 0, 0, NULL};

struct list *list_add(struct list *head, int val)
{
    struct list *temp = NULL;
    struct list *return_head = head;
    
    while(head){
        temp = head;
        head = head->next;
    }
    if(NULL == temp){
        temp = malloc(sizeof(struct list));
        if(temp){
            temp->val = val;
            temp->next = NULL;
            return_head = temp;
        }
    }else{
        head = malloc(sizeof(struct list));
        if(head){
            head->val = val;
            head->next = NULL;
            temp->next = head;
        }
    }
    g_root_info.num++;
    return return_head;
}

struct list *list_clean(struct list *head){
    struct list *temp;
    while(head){
        temp = head;
        head = head->next;
        free(temp);
    }
    g_root_info.num = 0;
    return NULL;
}

void list_get(struct list *head, int *p){
    int i = 0;
    while(head){
        p[i] = head->val;
        head = head->next;
        i++;
    }
}

int find_mode(struct TreeNode* root, int pre){
	if(root){
		pre = find_mode(root->left, pre);
		if(root->val != pre){
			g_root_info.cur_count = 0; 
			g_root_info.cur_count++;
            if(g_root_info.cur_count > g_root_info.max_count){
				g_root_info.max_count = g_root_info.cur_count;
				g_root_info.head = list_clean(g_root_info.head);
                g_root_info.head = list_add(g_root_info.head, root->val);
			}else if(g_root_info.cur_count == g_root_info.max_count){
                g_root_info.head = list_add(g_root_info.head, root->val);
            }
            pre = root->val;
		}else{
			g_root_info.cur_count++;
            if(g_root_info.cur_count > g_root_info.max_count){
				g_root_info.max_count = g_root_info.cur_count;
				g_root_info.head = list_clean(g_root_info.head);
                g_root_info.head = list_add(g_root_info.head, root->val);
			}else if(g_root_info.cur_count == g_root_info.max_count){
                g_root_info.head = list_add(g_root_info.head, root->val);
            }
		}
		
		pre = find_mode(root->right, pre);
	}
	return pre;
}

int* findMode(struct TreeNode* root, int* returnSize) {
    int *p = NULL;
    
    if(root){
        find_mode(root, root->val+1);
    }
    *returnSize = g_root_info.num;
    
    p = malloc(sizeof(int) * *returnSize);
    if(p){
        list_get(g_root_info.head, p);
        g_root_info.head = list_clean(g_root_info.head);
        g_root_info.max_count = 0;
        g_root_info.cur_count = 0;
    }
    
    return p;
}


*/


int idx;
int max;
int prev;
bool prev_valid;
void dfs(struct TreeNode* root, int* modes, int* count) {
    if (!root)
        return;
    dfs(root->left, modes, count);
    if (!prev_valid) {
        prev = root->val;
        *count = 1;
        prev_valid = true;
    } else {
        if (root->val == prev)
            (*count)++;
        else {
            prev = root->val;
            *count = 1;
        }
    }
    if (max != 0 &&
        *count == max)
        modes[idx++] = root->val;
    if (*count > max) {
        max = *count;
        memset(modes, 0, sizeof(int)*idx);
        idx = 0;
        modes[idx++] = root->val;
    }   
    dfs(root->right, modes, count);
    return;
}
int* findMode(struct TreeNode* root, int* returnSize) {
    int * modes = calloc(10000, sizeof(int));
    int count = 1;
    idx = 0;
    max = 0;
    prev_valid = false;  
    dfs(root, modes, &count);
    *returnSize = idx;
    return modes;
}

492. Construct the Rectangle

Description:

For a web developer, it is very important to know how to design a web page's size. So, given a specific rectangular web page’s area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements:

1. The area of the rectangular web page you designed must equal to the given target area.

2. The width W should not be larger than the length L, which means L >= W.

3. The difference between length L and width W should be as small as possible.

You need to output the length L and the width W of the web page you designed in sequence.

思路:本質上還是個找最大質數的問題。

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* constructRectangle(int area, int* returnSize) {
    
    *returnSize = 0;
    if(area < 1){
        return NULL;
    }
    int i;
    int *area_value = NULL;
    
    area_value = malloc(sizeof(int) * 2);
    if(area_value){
        *returnSize = 2;
        for(i = sqrt(area); i > 1; i--){
            if(0 == area % i){
                area_value[0] = area / i;
                area_value[1] = i;
                return area_value;
            }
        }
        area_value[0] = area;
        area_value[1] = 1;
    }
    
    return area_value;
}

645. Set Mismatch

Description:

The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.

Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.

思路:快排,然後找到重複的那個先,接下來分三種情況分析缺少的那個。

最佳思路:利用下標法。

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */

/*
int cmp_func(void const *p1, void const *p2)
{
    return *((int *)p1) - *((int *)p2);
}

int* findErrorNums(int* nums, int numsSize, int* returnSize) {
    qsort(nums, numsSize, sizeof(int), cmp_func);
    
    int i;
    int *p_return = NULL;
    p_return = malloc(sizeof(int) * 2);
    if(p_return){
        memset(p_return, 0, sizeof(int) * 2);
        *returnSize = 2;
    }
    for(i = 0; i < numsSize - 1; i++){
        if(nums[i] == nums[i+1]){
            p_return[0] = nums[i];
        }else if(1 != nums[i+1]-nums[i]){
            p_return[1] = nums[i]+1;
        }
    }
    if(0 != p_return[0] && 0 == p_return[1]){
        if(1 != nums[0]){
            p_return[1] = 1;
        }else{
            p_return[1] = nums[i] + 1;
        }
    }
    return p_return;
}*/



/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int *findErrorNums(int *nums, int numsSize, int *returnSize) {
        int num_dup, num_missing, i;
        int *retarr = (int *)calloc(2, sizeof(int));
        int *arr = (int *)calloc(numsSize + 1, sizeof(int));
        assert(numsSize > 1);
        for (i = 0; i < numsSize; i++) {
                assert(nums[i] > 0 && nums[i] <= numsSize);
                if (arr[nums[i]] == 1)
                        num_dup = nums[i];
                arr[nums[i]] = 1;
        }
        for (i = 1; i <= numsSize; i++) {
                if (arr[i] == 0) {
                        num_missing = i;
                        break;
                }
        }
        *returnSize = 2;
        retarr[0] = num_dup;
        retarr[1] = num_missing;
        return (retarr);
}