diff --git a/lectures/12_advanced_recursion/README.md b/lectures/12_advanced_recursion/README.md index b5bbee2..c8f19e5 100644 --- a/lectures/12_advanced_recursion/README.md +++ b/lectures/12_advanced_recursion/README.md @@ -94,7 +94,12 @@ into the scratch vector. Finally, the entire scratch vector is copied back. - Can we analyze this algorithm and determine the order notation for the number of operations it will perform? Count the number of pairwise comparisons that are required. -## 12.6 Example: Word Search +## 12.6 Merge Sort Exercises + +- [Leetcode problem 912: Sort an Array](https://leetcode.com/problems/sort-an-array/). Solution: [p1472_browserhistory.cpp](../../leetcode/p1472_browserhistory.cpp) +- [Leetcode problem 148: Sort List](https://leetcode.com/problems/sort-list/). Solution: [p148_sortlist.cpp](../../leetcode/p148_sortlist.cpp) + +## 12.7 Example: Word Search - Take a look at the following grid of characters. ```console @@ -117,11 +122,11 @@ daldruetryrt – At each such location, the occurrences of the second letter are sought in the 4 locations surrounding (r, c). - At each location where the second letter is found, a search is initiated in the 4 locations surrouding this second letter. -## 12.7 Exercise: Complete the implementation +## 12.8 Exercise: Complete the implementation - [Leetcode problem 79: Word Search](https://leetcode.com/problems/word-search/). Solution: [p1472_browserhistory.cpp](../../leetcode/p1472_browserhistory.cpp) -## 12.8 Summary of Nonlinear Word Search Recursion +## 12.9 Summary of Nonlinear Word Search Recursion - Recursion starts at each location where the first letter is found. - Each recursive call attempts to find the next letter by searching around the current position. When it is found, @@ -129,8 +134,6 @@ a recursive call is made. - The current path is maintained at all steps of the recursion. - The “base case” occurs when the path is full or all positions around the current position have been tried. -## 12.9 Leetcode Exercises +## 12.10 Leetcode Exercises - [Leetcode problem 704: Binary Search](https://leetcode.com/problems/binary-search/). Solution: [p141_linkedlistcycle.cpp](../../leetcode/p141_linkedlistcycle.cpp) -- [Leetcode problem 912: Sort an Array](https://leetcode.com/problems/sort-an-array/). Solution: [p1472_browserhistory.cpp](../../leetcode/p1472_browserhistory.cpp) -- [Leetcode problem 148: Sort List](https://leetcode.com/problems/sort-list/). Solution: [p1472_browserhistory.cpp](../../leetcode/p1472_browserhistory.cpp) diff --git a/leetcode/p148_sortlist.cpp b/leetcode/p148_sortlist.cpp new file mode 100644 index 0000000..727f113 --- /dev/null +++ b/leetcode/p148_sortlist.cpp @@ -0,0 +1,76 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + ListNode* mergeLists(ListNode* head1, ListNode* head2){ + // the value doesn't matter here + ListNode *head = new ListNode(-1); + ListNode* current; + current = head; + if(head1 == nullptr){ + return head2; + } + if(head2 == nullptr){ + return head1; + } + while(head1!=nullptr && head2!=nullptr){ + if(head1->val < head2->val){ + current->next = head1; + head1 = head1->next; + }else{ + current->next = head2; + head2 = head2->next; + } + current = current->next; + } + + // at this point, one of them has already been merged into the "New" list. + if(head1!=nullptr){ + // this means we still have some elements on the 1st list, now let's merge them into the "New" list. + current->next = head1; + }else{ + // this means we still have some elements on the 2nd list, now let's merge them into the "New" list. + current->next = head2; + } + return head->next; + } + + ListNode* sortList(ListNode* head) { + // base case + if(head==nullptr || head->next==nullptr){ + return head; + } + + // split the list + ListNode* slow=head; + ListNode* fast=head; + ListNode* tail1; + while(fast!=nullptr && fast->next!=nullptr){ + tail1 = slow; + slow = slow->next; + fast = fast->next; + fast = fast->next; + } + // this is the actual split action + tail1->next = nullptr; + // slow actually is now pointing to the head of the second half + // so let's just rename it to make the variable name more meaningful + ListNode* head2 = slow; + + // now let's do the recursion + head = sortList(head); + head2 = sortList(head2); + + // after the two sub-lists are sorted, we merge them into one list + head = mergeLists(head, head2); + return head; + } +};