leetcodo--Easy part

char* addBinary(char* a, char* b) {
    if (*a == '\0') return b;
    if (*b == '\0') return a;
    
    
    int index_a = strlen(a) - 1;
    int index_b = strlen(b) - 1;
    int carry = 0;
    int sum = 0;
    int index_ans = 0;
    char *ans = NULL;
    if (index_a >= index_b)
        ans = malloc(sizeof(char) * (index_a + 1 + 2)); //strlen(a) + 2, carry-bit and '\0'
    else
        ans = malloc(sizeof(char) * (index_b + 1 + 2));
    while (index_a >= 0 && index_b >= 0) {
        sum = (a[index_a] - '0') + (b[index_b] - '0') + carry;
        carry = sum/2;
        sum %= 2;
        ans[index_ans++] = sum + '0';
        --index_a;
        --index_b;
    }
    while (index_a >= 0) {
        sum = a[index_a] - '0' + carry;
        carry = sum / 2;
        sum %= 2;
        ans[index_ans++] = sum + '0';
        --index_a;
    }
    while (index_b >= 0) {
        sum = b[index_b] - '0' + carry;
        carry = sum / 2;
        sum %= 2;
        ans[index_ans++] = sum + '0';
        --index_b;
    }
    if (carry > 0) {
        ans[index_ans++] = carry + '0';
    }
    ans[index_ans] = '\0';
    return ans;
}
Add Binary

写得和add binary差不多,又臭又长

然后发现可以这么写

1 char* addBinary(char* a, char* b) {
 2     if (*a == '\0') return b;
 3     if (*b == '\0') return a;
 4     
 5     int len_a = strlen(a), len_b = strlen(b);
 6     char c = 0;
 7     int len_ans;
 8     char *ans = NULL;
 9 
10     len_ans = 2 + ((len_a > len_b) ? len_a : len_b);
11     ans = malloc(sizeof(char) * len_ans);
12     memset(ans, '0', sizeof(char) * len_ans);
13     ans[--len_ans] = '\0';
14     while (len_ans--) {
15         c += ((len_a > 0) ? (a[--len_a] - '0') : 0) + ((len_b > 0) ? (b[--len_b] - '0') : 0);
16         
17         ans[len_ans] = c % 2 + '0';
18         c /= 2;
19     }
20     if (ans[0] == '0') ans++;
21     return ans;
22 }

 

Climbing stairs

动态规划,爬到台阶n设为一个状态,state(n) 表示这个状态下有多少种爬法,如果一步只能走1或2阶楼梯,那么
现在的状态的前一个状态有两种可能,state(n-1)和state(n-2),故有state(n) = state(n-1) + state(n-2)。

初始状态:state(1) = 1, state(2) = 2;

int climbStairs(int n) { //n2 means n 
    int n2 = 1;
    int n1 = 2;
    int temp;
    if (n == 1) return n2;
    if (n == 2) return n1;
    
    for (int i = 3; i <= n; i++) {
        temp = n1 + n2;
        n2 = n1;
        n1 = temp;
    }
    return n1;
}

 

88.Merge Sorted Array

已知范围可以从后边开始。。

void merge(int* nums1, int m, int* nums2, int n) {
     int i1 = m - 1;
     int i2 = n -1;
     while (i1 >= 0 && i2 >= 0)
     {
         if (nums1[i1] > nums2[i2])
         {
             nums1[i1+i2+1] = nums1[i1];
             i1--;
         }
         else{
             nums1[i1+i2+1] = nums2[i2];
             i2--;
         }
     }
     while(i2 >= 0)
     {
          nums1[i1+i2+1] = nums2[i2];
          i2--;
     }
}
View Code

 

338.Counting Bits

本来想的是 any i in [0,num] 的解法,后来发现都已经用一个数组保存子问题了。。。也是一种DP吧

23ms

 1 int* countBits(int num, int* returnSize) {
 2     num++;
 3     *returnSize = num;
 4     int *bitCountArray = malloc(sizeof(int) * (*returnSize));
 5     bitCountArray[0] = 0;
 6     for (int i = 1; i < num; i++) {
 7         bitCountArray[i] = i&1 ? (bitCountArray[i>>1] + 1) : bitCountArray[i>>1]; 
 8     }
 9     return bitCountArray;
10 }

原来的解法

 1 int* countBits(int num, int* returnSize) {
 2     num++;
 3     *returnSize = num;
 4     int *bitCountArray = malloc(sizeof(int) * (*returnSize));
 5     bitCountArray[0] = 0;
 6     for (int i = 1; i < num; i++) {
 7         bitCountArray[i] = pop(i);
 8     }
 9     return bitCountArray;
10 }
11 inline int pop(unsigned x) {
12     x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
13     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
14     x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
15     x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
16     x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);
17     return x;
18 }

 

 

 

Best time to Buy and Sell

买卖石头是有顺序的,最简单的方法超时:

 1 int maxProfit(int* prices, int pricesSize) {
 2     int max_diff = 0;
 3     for (int i = 0; i < pricesSize; i++) {
 4         int diff = find_diff(i, pricesSize, prices);
 5         if (diff > max_diff) 
 6             max_diff = diff;
 7     }
 8     return max_diff;
 9 }
10 
11 int find_diff(int low, int high, int *prices) {
12     int max = prices[low];
13     for (int i = low; i < high; i++) {
14         if (prices[i] > max)
15             max = prices[i];
16     }
17     return max-prices[low];
18 }

可以换一个思路,虽然只能买卖一次,但是可以通过连续买卖模拟出最佳操作,因为profile = buy:day[i] + sell:day[i+1] = day[i+1] - day[i],

故如果在第k天存在最佳卖出的价格,其间存在关系 ((i+1) - i) + ((i+2) - (i+1)) +...+(k - (k-1)) = k - i ,

整个过程不用回退。(一句话解释:今天买明天卖,明天卖的可以在明天接着买回来)

所以可以写成一个online的算法(中途结束会给出近似解,有点像另一道最长子序的题)

 1 int maxProfit(int price[], int n)
 2 {
 3     int ret = 0, past = 0;
 4     for(int i = 1; i < n; i++)
 5     {
 6         ret += price[i] - price[i-1];
 7         if(ret < 0) ret = 0;
 8         if(ret > past) past = ret;
 9     }
10     return past;
11 }

 

1. Two Sum

用hash

 1 typedef struct linkList{
 2     int data;
 3     int index_nums;
 4     struct linkList *ptr;
 5 }linkList;
 6 
 7 void hashInsert(int index, int val, int hashSize, linkList *hashT){ //这是一个链表实现的哈希表,参数int i保存hash节点在原来数组中下标
 8     int tmp_val;
 9     tmp_val = (val < 0)? -val : val;
10     linkList *tmp_ptr = &hashT[tmp_val % hashSize];
11     while(tmp_ptr->ptr) tmp_ptr = tmp_ptr->ptr;
12     tmp_ptr->ptr = (linkList *)calloc(1, sizeof(linkList));
13     tmp_ptr->ptr->data = val;
14     tmp_ptr->ptr->index_nums = index;
15 }
16 
17 _Bool hashSearch(int exist_index, int val, int *return_index, int hashSize, linkList *hashT){ 
18     int tmp_val;
19     (val < 0) ? (tmp_val = (-1) * val) : (tmp_val = val);
20     linkList *tmp_ptr = &hashT[tmp_val % hashSize];
21     tmp_ptr = tmp_ptr->ptr;
22     while(tmp_ptr) {
23         if((tmp_ptr->data == val) && (tmp_ptr->index_nums != exist_index)){ //这个数不是其
24             *return_index = tmp_ptr->index_nums;
25             return true;
26         }
27         tmp_ptr = tmp_ptr->ptr;
28     }
29     return false;
30 }
31 
32 int* twoSum(int* nums, int numsSize, int target) {
33         linkList *hashT;
34     int i, *ans, val, index, hashTSize =  numsSize;
35 
36     hashT = (linkList *)calloc(hashTSize, sizeof(linkList));
37     ans = (int *)calloc(2, sizeof(int));
38     for(i = 0; i < numsSize; i++) hashInsert(i, nums[i], hashTSize, hashT);
39     for(i = 0; i < numsSize; i++) {
40         val = target - nums[i];
41         if(hashSearch(i, val, &index, hashTSize, hashT)){
42             ans[0] = i;
43             ans[1] = index;
44             break;
45         }
46     }
47     return ans;
48 }

 

6. ZigZag Conversion

题目给出的排版不清楚,看文字说明就好

因为读的顺序是 第0行->第1行->...->第nRows-1行,所以可以根据这一点创建一个大小为nRows的二维数组,[[row0],[row1],...,],分别保存每一行的数据。

然后遍历字符串,将每个字符放入它应在的数组,遍历后再把二维数组归为一个数组。

 1 char *convert(char *s, int nRows) {
 2     if (nRows <= 1 || s == NULL) return s;
 3     
 4     int row = 0;
 5     int step = 1;
 6     
 7     char **rows = malloc(nRows * sizeof(char *));
 8     for (int i = 0; i < nRows; i++) {
 9         rows[i] = calloc(300, sizeof(char));
10     }
11     for (int i = 0; i < strlen(s); i++) {
12         if (row == nRows-1) step = -1;
13         if (row == 0) step = 1;
14         strncat(rows[row], s+i, 1);
15         row += step;
16     }
17     
18     char *ans = calloc(300 * nRows, sizeof(char));
19     
20     for (int i = 0; i < nRows; i++) {
21         strcat(ans, rows[i]);
22     }
23     
24     for (int i = 0; i < nRows; i++) {
25         free(rows[i]);
26     }
27     free(rows);
28     
29     return ans;
30 }

 

还有一种解法就是根据每一行的数的下标关系将其放到对应的位置。

在内部循环中,每次放入两个同一行的数(如果不是第一行或者最后一行,则每次只放入一个数)

 1 char* convert(char* s, int numRows) {
 2     int n=strlen(s);
 3     char* a = malloc(sizeof(char) * (n+1));
 4     int k=0;
 5     if(numRows==1 || n<=numRows)return s;
 6     for(int i=0;i<numRows;i++)
 7     {
 8         for(int j=i;j<n;j+=2*(numRows-1))
 9         {
10             a[k++]=s[j];
11             if(i!=0 && i!=numRows-1)
12             {
13               int t=j+2*(numRows-1)-2*i;
14               if(t<n)
15               a[k++]=s[t];
16             }
17         }
18     }
19    a[k]='\0';  
20    return a;
21 }

 

 

7. Reverse Integer

主要考虑一下乘法溢出,这里用的csapp里的tmul_ok

 1 int reverse(int x) {
 2     int unit;
 3     int reverse_x = 0;
 4     int positive_x = x;
 5     while(positive_x/10 != 0)
 6     {
 7         unit = positive_x % 10;
 8         reverse_x = reverse_x*10 + unit;
 9         positive_x /= 10;
10     }
11     if(!tmul_ok(reverse_x, 10))
12         return 0;
13     reverse_x = reverse_x*10 + positive_x;
14     
15     return reverse_x;
16 }
17 int tmul_ok(int x, int y)
18 {
19     return !x || x*y/x == y;
20 }

 

8. String to Integer (atoi)

主要考虑加法溢出、乘法溢出  

 1 int myAtoi(char* str) {  
 2     int i, n, sign;
 3     
 4     for(i = 0; isspace(str[i]); i++)
 5         ;
 6     sign = ((str[i] == '-') ? -1 : 1);
 7     if(str[i] == '+' || str[i] == '-')
 8           i++;
 9     for(n = 0; isdigit(str[i]); i++){
10         if(!tmul_ok(10, n)){
11             return sign==1 ? 2147483647 : -2147483648;
12         }
13         n = 10 * n;
14         if(!tadd_ok(sign*n, sign*(str[i]-'0')))
15             return sign==1 ? 2147483647 : 2147483648;
16         n = n + str[i] - '0';
17     }
18     return sign * n;
19 }
20 int tmul_ok(int x, int y)
21 {
22     return x && x*y/x == y;
23 }
24 int tadd_ok(int x, int y)
25 {
26     int sum = x + y;
27     int neg_over = x < 0 && y < 0 && sum >= 0;
28     int pos_over = x >= 0 && y >= 0 && sum < 0;
29     return !neg_over && !pos_over;
30 }

 

9. Palindrome Number

 1 bool isPalindrome(int x) {
 2     if (x < 0) return false;
 3     int y=0;
 4     int xx=x;
 5     while (xx>0) {
 6         y = y*10 + xx%10;
 7         xx/=10;
 8     }
 9     return (y == x);
10 }

 

14. Longest Common Prefix

一个二维数组strs,有strsSize个字符指针

如果每次都完整地比较两个相邻的字符串,那么当遇到不相等的字符时就会跳出,忽略了后面可能更短的部分,比如["abab","aba",""]所以每次必须比较同一个位置上所有字符串的字符。

 1 char* longestCommonPrefix(char** strs, int strsSize) {
 2     int i,j;
 3     char* s="";
 4     if(strsSize==0) return s;
 5     for(i = 1; i < strsSize; i++) 
 6     for (j = 0; j < strlen(*strs); j++)
 7       
 8         if(*(*(strs+i)+j)!=*(*strs+j)) goto EXIT; 
 9    EXIT: 
10     if(j==0) return s;
11     *(*strs+j)='\0';
12   return *strs;
13 }

 

19. Remove Nth Node From End of List

可以设置两个节点,倒数第n个也就是其中一个节点比另一个节点“慢”n个节点

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     struct ListNode *next;
 6  * };
 7  */
 8 struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
 9     struct ListNode *scout = head, *target = head;
10     int count = 0;
11     while(scout){
12         scout = scout->next;
13         if(count > n) target = target->next;
14         count++;
15     }
16     if(count > n) target->next = target->next->next;
17     else head = head->next;
18     return head;
19 }

 

20. Valid Parentheses

经典的括号匹配问题

 1 bool isValid(char* s)
 2 {
 3     char a[10000];
 4     int i, j, k, ct1=0;
 5     for(i = 0; i < strlen(s); i++)
 6     {
 7         switch(s[i])
 8         {
 9             case '(': a[ct1]='(';ct1++;break;
10             case '{': a[ct1]='{';ct1++;break;
11             case '[': a[ct1]='[';ct1++;break;
12             case ')': if(a[ct1-1]=='(')ct1--;else return false;break;
13             case '}': if(a[ct1-1]=='{')ct1--;else return false;break;
14             case ']': if(a[ct1-1]=='[')ct1--;else return false;break;
15         }
16     }
17     if(ct1==0)
18         return true;
19     else
20         return false;
21 }

 

21. Merge Two Sorted Lists

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     struct ListNode *next;
 6  * };
 7  */
 8 struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
 9     struct ListNode* dummy = malloc(sizeof(struct ListNode));
10     struct ListNode* ptr = dummy;
11     dummy->next = NULL;
12     if (l1 == NULL)
13         return l2;
14     else if (l2 == NULL)
15         return l1;
16     while (l1 != NULL && l2 != NULL) {
17         if (l1->val > l2->val) {
18             ptr->next = l2;
19             l2 = l2->next;
20         }
21         else {
22             ptr->next = l1;
23             l1 = l1->next;
24         }
25         ptr = ptr->next;
26     }
27     if (l1 == NULL) 
28         ptr->next = l2;
29     else if(l2 == NULL)
30         ptr->next = l1;
31     ptr = dummy->next;
32     free(dummy);
33     return ptr;
34 }

 

24. Swap Nodes in Pairs

基本的链表变换操作

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     struct ListNode *next;
 6  * };
 7  */
 8 struct ListNode* swapPairs(struct ListNode* head) {
 9     if(head == NULL)
10         return head;
11     if(head->next == NULL)
12         return head;
13     struct ListNode *ptr_pre;
14     struct ListNode *ptr;
15     struct ListNode *ptr_next;
16     struct ListNode *dummy = malloc(sizeof(struct ListNode));
17     ptr = head;
18     ptr_next = head->next;
19     ptr_pre = dummy;
20     ptr_pre->next = ptr;
21     while(ptr_next){
22         ptr->next = ptr_next->next;
23         ptr_next->next = ptr;
24         ptr_pre->next = ptr_next;
25         
26         ptr_pre = ptr;
27         if(ptr->next)
28             ptr = ptr->next;
29         ptr_next = ptr->next;
30     }
31     head = dummy->next;
32     free(dummy);
33     return head;
34 }

 

26. Remove Duplicates from Sorted Array

设置一个index指向最后一个未重复的元素

 1 int removeDuplicates(int* nums, int numsSize) {
 2     if (numsSize == 0) return 0;
 3     int i = 0;
 4     int j;
 5     for (j = 1; j < numsSize; j++) {
 6         if (nums[i] != nums[j]) {
 7             i++;
 8             nums[i] = nums[j];
 9         }
10     }
11     return i+1;
12 }

 

27. Remove Element

不必真的去除val,因为不能申请额外的空间,只要设置一个普通的index i一直前进,然后再设置一个指向除了val以外的数的index

 1 int removeElement(int* nums, int numsSize, int val) {
 2     int i = 0;
 3     int j = 0;
 4     while (i < numsSize) {
 5         if (nums[i] == val) {
 6             i++;
 7             continue;
 8         }
 9         else {
10             nums[j] = nums[i];
11             i++;
12             j++;
13             continue;
14         }
15     }
16     return j;
17 }

 

28. Implement strStr()

暴力搜索,参考K&R的实现

 1 int strStr(char *haystack, char *needle)
 2 {
 3     int i, j, k;
 4     if(needle == NULL) return 0;
 5     for(i = 0; haystack[i] != '\0'; i++){
 6         for(j = i, k = 0; needle[k] != '\0' && needle[k] == haystack[j]; j++, k++)
 7             ;
 8         if(k > 0 && needle[k] == '\0')
 9             return i;
10     }
11     return -1;
12 }


亦可使用KMP

 

posted @ 2016-10-17 13:45  autoria  阅读(265)  评论(0编辑  收藏  举报