国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

LeetCode Week2: Maximum Subarray、Merge k Sorted Lists

2019-11-06 07:18:11
字體:
來源:轉載
供稿:網友

  這周主要實現了LeetCode Algorithms中的Divide-And-Conquer的題目,這里選擇二道題來分析,分別是Maximum Subarray(easy)、Merge k Sorted Lists(Hard)。

一、Maximum Subarray

題目描述:Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum = 6.

分析:這個題最開始的做法是采用了分治法,參考《算法分析》4.1的最大子數組問題??紤]最大值會出現的三種情況,即將數組分為三個部分,最大子序列可能會是前半部分或后半部分或者是跨越了中點的序列中,比如S1max、S2maxS3max。 這里寫圖片描述

對于S2max對應的序列,從中間點開始,往左部分的序列和是左邊序列的最大序列和,往右部分的序列亦然。這樣的話可以直接從中點分別往左和右開始計算,得出兩邊的最大序列和,那么跨越中點可以得到的最大序列和就是兩邊序列和的累加;

對于S1max、S3max對應的序列,可以直接遞歸調用上述分割過程,對左數組(A0……Amid)和右數組(Amid……An)和跨越中點的序列分別求其最大子序列的和;


  最終返回三種計算中的最大的序列和即可。這樣的做法的時間復雜度是T(n)=2T(n2)+O(n),套用大師定理即可得到T(n)=O(nlogn)

  分治法的結果如下:

class Solution {public: int maxSubArray(vector<int>& nums) { return findMaxArray(nums,0,nums.size()-1); } int findMaxArray(vector<int>& nums,int low, int high){ if(high == low){ return nums[low]; } else{ int mid = (high+low)/2; return max(findMaxArray(nums,low,mid),findMaxArray(nums,mid+1,high),findMaxCrossArray(nums,low,mid,high)); } } int findMaxCrossArray(vector<int>& nums, int low, int mid, int high){ int leftsum = -100, rightsum = -100; int sum = 0; for(int i = mid; i >= low;i--) { sum += nums[i]; if(sum>leftsum) leftsum = sum; } sum = 0; for(int i = mid+1; i <=high ;i++) { sum += nums[i]; if(sum>rightsum) rightsum = sum; } return leftsum+rightsum; } int max(int m1,int m2,int m3){ if(m1>=m2 && m1>=m3) return m1; else if(m2>=m1 && m2>=m3) return m2; else return m3; }};

  但是,這樣的分治法,其實是很麻煩的,RunTime為13ms??梢灾苯油ㄟ^優化把算法的復雜度降到O(n)

  對于數組,我們可以這樣考慮:

  我們定義SUMnow為當前的序列的和,SUMmax是已經讀取到的序列中可以計算出的最大序列和?,F在考慮加上下一個元素之后的新的SUMnow:

下一個元素本身就比SUMnow大的話,那么就從這個元素開始,重新計算SUMnow;如果SUMnow>SUMmax,SUMmax = SUMnow。

  代碼的過程可以寫作下面的形式:

class Solution {public: int maxSubArray(vector<int>& nums) { int sum_now = 0; int sum_max = nums[0]; for(int i = 0;i < nums.size();i++){ sum_now += nums[i]; if(nums[i]>= sum_now) sum_now = nums[i]; if(sum_now >= sum_max) sum_max = sum_now; } return sum_max; }};

  可以看出此時的算法的復雜度只有O(n)了,通過提交發現RunTime也變為了9ms,得到了很大的提升。   

二、Merge k Sorted Lists

題目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Subscribe to see which companies asked this question.

分析:其實這個題的難度并不大,可以直接通過歸并排序完成。最主要的就是了解歸并排序的流程。      歸并排序是典型的分治模式的算法,它主要是通過把n個元素分成各有n2個元素的兩個子序列,排序兩個子序列,最后合并兩個子序列。而n2個元素還可以分為兩個元素數為n4的子序列,重復進行排序和合并,即為歸并排序。歸并排序的關鍵是“合并”。      如下圖所示,這里我們假設某一段序列長度為10,我們將其對半分成兩個子序列后對其分別排序,之后將兩個序列合并。每次都取出兩個序列較小的一個元素,被選擇的序列下一次被用來對比的就是下一位元素。這樣子不斷的對比選擇,就能把兩個子序列合并了。

  歸并排序合并過程

  題目要求的是對多條鏈表的合并,需要注意的是鏈表的長度都是不一致,所以需要在合并過程時判斷是否應該繼續用某一序列的下一位來判斷取值。

  代碼如下所示:

class Solution {public: ListNode* mergeKLists(vector<ListNode*>& lists) { if(lists.empty()) return nullptr; return mergesort(lists,0,lists.size()-1); } ListNode* mergesort(vector<ListNode*>& lists, int p, int r){ if (p<r) return merge(mergesort(lists,p,(p+r)/2),mergesort(lists,(p+r)/2+1,r)); else return lists[p]; } ListNode* merge(ListNode* l1, ListNode* l2){ if(l1 == NULL) return l2; if(l2 == NULL) return l1; ListNode* result = new ListNode(0); ListNode* head = result; while(l1 != NULL && l2 != NULL){ if(l1->val < l2->val){ head->next = new ListNode(l1->val); l1 = l1->next; } else{ head->next = new ListNode(l2->val); l2 = l2->next; } head = head->next; } if(l1 == NULL) head->next = l2; else if(l2 == NULL) head->next = l1; return result->next; }};

  直接使用歸并排序,每次都選擇分割兩個序列,算法負責度可以寫作T(n)=2T(n/2)+O(n),即T(n)=O(nlogn)

  總結:其實這周實現的算法都不是很難,但是可能我更多的時間都花在了怎么去優化它們了,最開始總是有先入為主的想法,分治一定會比較快,但其實不盡然(當然也有可能是我想的分治法比較麻煩==)??傊?,我覺得這周選擇的題目不僅剛好把課上學到的分治法的分析思想用上了,也讓我學著去思考優化的問題,感覺收獲頗多,接下來還是要好好刷題^^


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 土默特左旗| 玉屏| 突泉县| 海丰县| 马边| 榆社县| 神池县| 临潭县| 三门县| 普安县| 鄂托克旗| 福鼎市| 柘城县| 阜康市| 商都县| 阳东县| 金寨县| 孟连| 简阳市| 资源县| 万安县| 大安市| 儋州市| 凌源市| 沧源| 靖江市| 措勤县| 乌兰浩特市| 宿松县| 灵宝市| 夏河县| 西华县| 曲沃县| 封丘县| 施秉县| 白河县| 开化县| 锦屏县| 建平县| 日喀则市| 西吉县|