leetcode -- hard part

10. Regular Expression Matching

很容易写出

 1 bool comp(char a, char b) {
 2         return a && (a==b || b=='.');
 3     }
 4 bool isMatch(char *s, char *p) {
 5         while (*s || *p) {
 6             if (p[0] && p[1] == '*') {
 7                 return isMatch(s, p+2) || (comp(*s, *p) && isMatch(s+1, p));
 8             }
 9             else 
10                 if (!comp(*s++, *p++)) return false;
11         }
12         return true;
13 }

 

comp函数成立的条件是 a存在b存在,a和b相等,或b为一个通配符,和while循环搭配,可以排除pattern比string多的情况。

首先判断pattern是不是一个 _* (这里用_表示任意一个字符),如果是,那么这个pattern是可以忽略的,所以调用isMatch判断忽略的情况,如果不忽略则调用comp判断_和字符*s是否匹配,并继续判断下一个字符。

如果pattern不是一个_*,则直接调用comp判断_和字符*s是否匹配。

可以稍微更改一下减少递归

 1 bool isMatch(char* s, char* p) {
 2     while (*s) {
 3         if (*p&&*(p+1)=='*') { //get a _* pattern.
 4             if (*s==*p||*p=='.') {
 5                 if (isMatch(s, p+2)) {return true;} 
 6                 else {s++; continue;}
 7             }
 8              //_ in _* is not match, move to next pattern.
 9             else {p+=2;continue;}
10         }
11         if (*s==*p||*p=='.') {s++; p++; continue;}// match a single character, move to next s and p.
12         else return false;
13     }
14     
15     while(*p&&*(p+1)=='*') p+=2; //skip _* pattern
16     return *p=='\0';
17 }

4. Median of Two Sorted Arrays

由于是找中间数,所以要分奇偶两种情况。

 1 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
 2     int odd = (nums1Size + nums2Size) % 2;
 3     int mid = (nums1Size + nums2Size) / 2;
 4     double ans;
 5     int *s1 = nums1;
 6     int *s2 = nums2;
 7     int cur;
 8     int i;
 9     int next;
10     if(odd){
11         for(i = 0; i <= mid; i++){
12             if(((s2 - nums2) < nums2Size) && ((s1 - nums1) < nums1Size)){
13                 if(*s1 > *s2) cur = *s2++;
14                 else cur = *s1++;
15             }else{
16                 if((s2 - nums2) < nums2Size) cur = *s2++;
17                 else cur = *s1++;
18             }
19         }
20         ans = cur;
21     }
22     else{
23         for(i = 0; i < mid; i++){
24             if(((s2 - nums2) < nums2Size) && ((s1 - nums1) < nums1Size)){
25                 if(*s1 > *s2) cur = *s2++;
26                 else cur = *s1++;
27             }else{
28                 if((s2 - nums2) < nums2Size) cur = *s2++;
29                 else cur = *s1++;
30             }
31         }
32         
33         if(((s2 - nums2) < nums2Size) && ((s1 - nums1) < nums1Size)){
34             if(*s1 > *s2) next = *s2;
35             else next = *s1;
36         }
37         else{
38             if((s2 - nums2) < nums2Size) next = *s2;
39             else next = *s1;
40         }
41         ans = ((double)cur+next)/2;
42     }
43  
44     return ans;    
45 }

精简一下得到

 1 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
 2     int odd = (nums1Size + nums2Size) % 2;
 3     int mid = (nums1Size + nums2Size) / 2;
 4     double ans;
 5     int *s1 = nums1;
 6     int *s2 = nums2;
 7     int cur;
 8     int i;
 9     int next;
10 
11      for(i = 0; i < mid + odd; i++){
12          if(((s2 - nums2) < nums2Size) && ((s1 - nums1) < nums1Size)){
13              if(*s1 > *s2) cur = *s2++;
14              else cur = *s1++;
15          }else{
16              if((s2 - nums2) < nums2Size) {cur = *s2++; next = *s2;}
17              else cur = *s1++;
18          }
19      }
20      
21     if(odd) ans = cur;
22     else{
23         if(((s2 - nums2) < nums2Size) && ((s1 - nums1) < nums1Size)){
24             if(*s1 > *s2) next = *s2;
25             else next = *s1;
26         }
27         else{
28             if((s2 - nums2) < nums2Size) next = *s2;
29             else next = *s1;
30         }
31         ans = ((double)cur+next)/2;
32     }
33  
34     return ans;    
35 }

暂时没想到怎么进一步整合

 

23. Merge k Sorted Lists

算是hard里面不hard的题

第一种方法是像二分法一样分治,代码写出来也像二分法

void MIN_HEAP_SORT(struct ListNode **lists, int index_i,int size)
{
    int left = index_i*2 + 1;
    int right= index_i*2 + 2;
    if(left>=size)
        return;
    int min;
    if(right>=size)
        min = left;
    else
        min = lists[left]->val<lists[right]->val?left:right;
    if(lists[index_i]->val>lists[min]->val){
        struct ListNode *temp = lists[index_i];
        lists[index_i] = lists[min];
        lists[min] = temp;
        MIN_HEAP_SORT(lists,min,size);
    }
}

void BuildHeap(struct ListNode **lists,int size)
{
    for(int i=(size-1)/2;i>=0;--i){
        MIN_HEAP_SORT(lists,i,size);
    }
}

struct ListNode *mergeKLists(struct ListNode *lists[], int listsSize) {
    if (listsSize == 0)
        return NULL;//1
    struct ListNode *head = malloc(sizeof(struct ListNode));
    struct ListNode *int_max = malloc(sizeof(struct ListNode));
    int_max->val = INT_MAX;
    int_max->next = NULL;
    struct ListNode *travel = head;
    for (int i = 0; i < listsSize; ++i){
        if (lists[i] == NULL)
            lists[i] = int_max;
    }/*remove those NULL ptr*/
    BuildHeap(lists, listsSize);
    while (lists[0] != int_max) {
        travel->next = lists[0];
        travel = lists[0];
        lists[0] = lists[0]->next;
        if (lists[0] == NULL)
            lists[0] = int_max;
        MIN_HEAP_SORT(lists, 0, listsSize);
    }
    travel->next = NULL;
    return head->next;
}

第二种方法是建立一个最小堆

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2);

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
  if(listsSize == 0)      return NULL;
  else if(listsSize == 1) return lists[0];
  else if(listsSize == 2) return mergeTwoLists(lists[0], lists[1]);

  //divide and conquor if listsSize is still > 3
  return mergeTwoLists(mergeKLists(lists, listsSize/2),
                       mergeKLists(lists+listsSize/2, listsSize - listsSize/2));
}

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
  if( (l1 == NULL) && (l2 == NULL)) return NULL;
  else if(l1 == NULL)               return l2;
  else if(l2 == NULL)               return l1;
  
  if(l1->val > l2->val)
  {
    l2->next = mergeTwoLists(l1, l2->next);
    return l2;
  }
  else
  {
    l1->next = mergeTwoLists(l1->next, l2);
    return l1;
  }
  return NULL;
}

 

posted @ 2016-10-23 21:16  autoria  阅读(230)  评论(0)    收藏  举报