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; }