楼主: zhuli19901106
跳转到指定楼层
上一主题 下一主题
收起左侧

分享我的Lintcode题解,目前进度244/248

 
🔗
 楼主| zhuli19901106 2015-7-26 20:02:58 | 只看该作者
全局:
Sort Letters by Case
题意:给定一个只有字母的字符串,把小写放前面,大写放后面。
解法:其实还是数组划分。
代码:
  1. #include <cctype>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param chars: The letters array you should sort.
  7.      */
  8.     void sortLetters(string &letters) {
  9.         string &s = letters;
  10.         int n = s.length();
  11.         int i = 0;
  12.         int j = n - 1;
  13.         while (true) {
  14.             while (i <= j && islower(s[i])) {
  15.                 ++i;
  16.             }
  17.             while (i <= j && isupper(s[j])) {
  18.                 --j;
  19.             }
  20.             if (i >= j) {
  21.                 break;
  22.             }
  23.             swap(s[i++], s[j--]);
  24.         }
  25.     }
  26. };
复制代码
复杂度:时间O(N),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:08:22 | 只看该作者
全局:
Palindrome Partitioning II
题意:给定一个字符串,允许你把它分割成一些回文串。请问最少能分成几段?
解法:很典型的DP题目。dp{i}{j}表示s{i...j}最少能分成几段。
代码:
  1. #include <vector>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param s a string
  7.      * @return an integer
  8.      */
  9.     int minCut(string s) {
  10.         int n = s.length();
  11.         if (n <= 1) {
  12.             return 0;
  13.         }
  14.         vector<vector<bool> > pal;
  15.         pal.resize(n, vector<bool>(n, false));
  16.         int i, j;
  17.         for (i = 0; i < n; ++i) {
  18.             pal[i][i] = true;
  19.         }
  20.         for (i = 0; i < n - 1; ++i) {
  21.             pal[i][i + 1] = s[i] == s[i + 1];
  22.         }
  23.         for (i = 2; i < n; ++i) {
  24.             for (j = 0; j + i < n; ++j) {
  25.                 pal[j][j + i] = s[j] == s[j + i] && pal[j + 1][j + i - 1];
  26.             }
  27.         }
  28.         
  29.         vector<int> dp;
  30.         dp.resize(n);
  31.         for (i = 0; i < n; ++i) {
  32.             dp[i] = i + 1;
  33.             if (pal[0][i]) {
  34.                 dp[i] = 1;
  35.                 continue;
  36.             }
  37.             for (j = 0; j < i; ++j) {
  38.                 if (pal[j + 1][i]) {
  39.                     dp[i] = min(dp[i], dp[j] + 1);
  40.                 }
  41.             }
  42.         }
  43.         return dp[n - 1] - 1;
  44.     }
  45. };
复制代码
复杂度:时间O(N ^ 2),空间O(N ^ 2)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:10:58 | 只看该作者
全局:
Minimum Path Sum
题意:Frequently Ask Question
解法:Frequently Answered Question
代码:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param grid: a list of lists of integers.
  7.      * @return: An integer, minimizes the sum of all numbers along its path
  8.      */
  9.     int minPathSum(vector<vector<int> > &grid) {
  10.         vector<vector<int> > &a = grid;
  11.         int n, m;
  12.         n = a.size();
  13.         if (n == 0) {
  14.             return 0;
  15.         }
  16.         m = a[0].size();
  17.         if (m == 0) {
  18.             return 0;
  19.         }
  20.         int i, j;
  21.         
  22.         for (i = 1; i < n; ++i) {
  23.             a[i][0] += a[i - 1][0];
  24.         }
  25.         for (i = 1; i < m; ++i) {
  26.             a[0][i] += a[0][i - 1];
  27.         }
  28.         for (i = 1; i < n; ++i) {
  29.             for (j = 1; j < m; ++j) {
  30.                 a[i][j] += min(a[i][j - 1], a[i - 1][j]);
  31.             }
  32.         }
  33.         return a[n - 1][m - 1];
  34.     }
  35. };
复制代码
复杂度:时间O(N * M),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:39:05 | 只看该作者
全局:
Merge k Sorted Lists
题意:给定K个有序链表,把它们归并成一个有序链表。
解法:借助最小堆进行归并。把K个链表的表头放进堆中,每次选取最小的一个拿出来,并把它向前移一位。
代码:
  1. #include <queue>
  2. using namespace std;
  3. /**
  4. * Definition of ListNode
  5. * class ListNode {
  6. * public:
  7. *     int val;
  8. *     ListNode *next;
  9. *     ListNode(int val) {
  10. *         this->val = val;
  11. *         this->next = NULL;
  12. *     }
  13. * }
  14. */
  15. struct Comp {
  16.     bool operator () (ListNode *&x, ListNode *&y)
  17.     {
  18.         return x->val > y->val;
  19.     }
  20. };

  21. class Solution {
  22. public:
  23.     /**
  24.      * @param lists: a list of ListNode
  25.      * @return: The head of one sorted list.
  26.      */
  27.     ListNode *mergeKLists(vector<ListNode *> &lists) {
  28.         priority_queue<ListNode *, vector<ListNode *>, Comp> pq;
  29.         for (auto &it: lists) {
  30.             if (it != NULL) {
  31.                 pq.push(it);
  32.             }
  33.         }
  34.         ListNode *h, *t;
  35.         ListNode *p, *q;
  36.         
  37.         h = t = NULL;
  38.         while (!pq.empty()) {
  39.             p = pq.top();
  40.             q = p->next;
  41.             pq.pop();
  42.             if (q != NULL) {
  43.                 pq.push(q);
  44.             }
  45.             
  46.             if (h != NULL) {
  47.                 t->next = p;
  48.                 t = t->next;
  49.             } else {
  50.                 h = t = p;
  51.             }
  52.             t->next = NULL;
  53.         }
  54.         return h;
  55.     }
  56. };
复制代码
复杂度:时间O(K * log(K))空间O(K)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:44:44 | 只看该作者
全局:
本帖最后由 zhuli19901106 于 2015-7-26 20:50 编辑

又被吞掉一题:Merge k Sorted Lists

此处要特别提一下,这道题和下面这题在思路上是有关联的,有兴趣的同学可以做一下:
http://ac.jobdu.com/problem.php?pid=1534
关键词:杨氏矩阵,Young Tableau

此处特别感谢mgccl提供的O(K)时间的算法,实现用的是Haskell。比常见的O(K * log(K))更优化,可以参见他的博客。
http://www.chaoxuprime.com/posts/2014-04-02-selection-in-a-sorted-matrix.html
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:47:49 | 只看该作者
全局:
Linked List Cycle
题意:给定一个单链表,判断是否有环。
解法1:用哈希。
代码1:
  1. #include <unordered_set>
  2. using namespace std;
  3. /**
  4. * Definition of ListNode
  5. * class ListNode {
  6. * public:
  7. *     int val;
  8. *     ListNode *next;
  9. *     ListNode(int val) {
  10. *         this->val = val;
  11. *         this->next = NULL;
  12. *     }
  13. * }
  14. */
  15. class Solution {
  16. public:
  17.     /**
  18.      * @param head: The first node of linked list.
  19.      * @return: True if it has a cycle, or false
  20.      */
  21.     bool hasCycle(ListNode *head) {
  22.         if (head == NULL) {
  23.             return NULL;
  24.         }
  25.         unordered_set<ListNode *> us;
  26.         ListNode *p = head;
  27.         while (p != NULL) {
  28.             if (us.find(p) != us.end()) {
  29.                 return true;
  30.             }
  31.             us.insert(p);
  32.             p = p->next;
  33.         }
  34.         return false;
  35.     }
  36. };
复制代码
复杂度1:时间O(N),空间O(N)。

解法2:追赶法。
代码2:
  1. // The running pointers
  2. /**
  3. * Definition of ListNode
  4. * class ListNode {
  5. * public:
  6. *     int val;
  7. *     ListNode *next;
  8. *     ListNode(int val) {
  9. *         this->val = val;
  10. *         this->next = NULL;
  11. *     }
  12. * }
  13. */
  14. class Solution {
  15. public:
  16.     /**
  17.      * @param head: The first node of linked list.
  18.      * @return: True if it has a cycle, or false
  19.      */
  20.     bool hasCycle(ListNode *head) {
  21.         if (head == NULL) {
  22.             return NULL;
  23.         }
  24.         ListNode *p1, *p2;
  25.         
  26.         p1 = head;
  27.         p2 = head->next;
  28.         while (p2 != NULL) {
  29.             p1 = p1->next;
  30.             p2 = p2->next;
  31.             if (p2 == NULL) {
  32.                 return false;
  33.             }
  34.             p2 = p2->next;
  35.             if (p1 == p2) {
  36.                 return true;
  37.             }
  38.         }
  39.         return false;
  40.     }
  41. };
复制代码
复杂度2:时间O(N ^ 2),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 20:54:11 | 只看该作者
全局:
Linked List Cycle II
题意:hard难度。给定一个单链表,判断是否有环。如果有,返回进入环的第一个节点;如果没有,返回NULL。
解法1:用哈希。
代码1:
  1. // O(n) time and O(n) space
  2. #include <unordered_set>
  3. using namespace std;
  4. /**
  5. * Definition of ListNode
  6. * class ListNode {
  7. * public:
  8. *     int val;
  9. *     ListNode *next;
  10. *     ListNode(int val) {
  11. *         this->val = val;
  12. *         this->next = NULL;
  13. *     }
  14. * }
  15. */
  16. class Solution {
  17. public:
  18.     /**
  19.      * @param head: The first node of linked list.
  20.      * @return: The node where the cycle begins.
  21.      *           if there is no cycle, return null
  22.      */
  23.     ListNode *detectCycle(ListNode *head) {
  24.         unordered_set<ListNode *> us;
  25.         ListNode *p = head;
  26.         while (p != NULL) {
  27.             if (us.find(p) != us.end()) {
  28.                 break;
  29.             }
  30.             us.insert(p);
  31.             p = p->next;
  32.         }
  33.         return p;
  34.     }
  35. };
复制代码
复杂度1:时间O(N),空间O(N)。

解法2:这个题目碰见好几次了,第一次碰见的时候觉得这解法非常巧妙。关键思路在于如果你从头开始遍历,先到达了p->next,后到达p,那么这个节点p有什么特殊之处
代码2:
  1. /**
  2. * Definition of ListNode
  3. * class ListNode {
  4. * public:
  5. *     int val;
  6. *     ListNode *next;
  7. *     ListNode(int val) {
  8. *         this->val = val;
  9. *         this->next = NULL;
  10. *     }
  11. * }
  12. */
  13. class Solution {
  14. public:
  15.     /**
  16.      * @param head: The first node of linked list.
  17.      * @return: The node where the cycle begins.
  18.      *           if there is no cycle, return null
  19.      */
  20.     ListNode *detectCycle(ListNode *head) {
  21.         ListNode *p1, *p2;
  22.         
  23.         p1 = head;
  24.         while (p1 != NULL) {
  25.             p2 = head;
  26.             while (true) {
  27.                 if (p2 == p1->next) {
  28.                     return p2;
  29.                 }
  30.                 if (p2 == p1) {
  31.                     break;
  32.                 }
  33.                 if (p2 == NULL) {
  34.                     return NULL;
  35.                 }
  36.                 p2 = p2->next;
  37.             }
  38.             p1 = p1->next;
  39.         }
  40.         return NULL;
  41.     }
  42. };
复制代码
复杂度2:时间O(N ^ 2),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 21:05:46 | 只看该作者
全局:
Convert Sorted List to Binary Search Tree
题意:给定一个有序链表,把它转换为平衡BST。
解法1:递归解决。还是对半分,中间作为根节点。不过链表没法随机访问,所以找到中点需要O(N)时间。
代码1:
  1. /**
  2. * Definition of ListNode
  3. * class ListNode {
  4. * public:
  5. *     int val;
  6. *     ListNode *next;
  7. *     ListNode(int val) {
  8. *         this->val = val;
  9. *         this->next = NULL;
  10. *     }
  11. * }
  12. * Definition of TreeNode:
  13. * class TreeNode {
  14. * public:
  15. *     int val;
  16. *     TreeNode *left, *right;
  17. *     TreeNode(int val) {
  18. *         this->val = val;
  19. *         this->left = this->right = NULL;
  20. *     }
  21. * }
  22. */
  23. class Solution {
  24. public:
  25.     /**
  26.      * @param head: The first node of linked list.
  27.      * @return: a tree node
  28.      */
  29.     TreeNode *sortedListToBST(ListNode *head) {
  30.         if (head == NULL) {
  31.             return NULL;
  32.         }
  33.         
  34.         ListNode *p;
  35.         int len = 0;
  36.         p = head;
  37.         while (p != NULL) {
  38.             p = p->next;
  39.             ++len;
  40.         }
  41.         return convert(head, len);
  42.     }
  43. private:
  44.     TreeNode *convert(ListNode *head, int len) {
  45.         if (len == 0) {
  46.             return NULL;
  47.         }
  48.         if (len == 1) {
  49.             return new TreeNode(head->val);
  50.         }
  51.         if (len == 2) {
  52.             TreeNode *h = new TreeNode(head->val);
  53.             h->right = new TreeNode(head->next->val);
  54.             return h;
  55.         }
  56.         int i;
  57.         ListNode *p = head;
  58.         for (i = 1; i <= (len - 1) / 2; ++i) {
  59.             p = p->next;
  60.         }
  61.         TreeNode *r = new TreeNode(p->val);
  62.         r->left = convert(head, (len - 1) / 2);
  63.         r->right = convert(p->next, len / 2);
  64.         return r;
  65.     }
  66. };
复制代码
复杂度1:时间O(N * log(N)),空间O(N)。

解法2:用O(N)的时间把链表变成数组,然后用数组建立BST。这两步都是O(N),所以总体是线性算法。其实这种思路最实用,如果1+1<3,为何非要选3呢。一步到位不一定最好。
代码2:
  1. /**
  2. * Definition of ListNode
  3. * class ListNode {
  4. * public:
  5. *     int val;
  6. *     ListNode *next;
  7. *     ListNode(int val) {
  8. *         this->val = val;
  9. *         this->next = NULL;
  10. *     }
  11. * }
  12. * Definition of TreeNode:
  13. * class TreeNode {
  14. * public:
  15. *     int val;
  16. *     TreeNode *left, *right;
  17. *     TreeNode(int val) {
  18. *         this->val = val;
  19. *         this->left = this->right = NULL;
  20. *     }
  21. * }
  22. */
  23. class Solution {
  24. public:
  25.     /**
  26.      * @param head: The first node of linked list.
  27.      * @return: a tree node
  28.      */
  29.     TreeNode *sortedListToBST(ListNode *head) {
  30.         if (head == NULL) {
  31.             return NULL;
  32.         }
  33.         
  34.         ListNode *p = head;
  35.         vector<int> A;
  36.         while (p != NULL) {
  37.             A.push_back(p->val);
  38.             p = p->next;
  39.         }
  40.         return sortedArrayToBST(A);
  41.     }
  42.    
  43.     TreeNode *sortedArrayToBST(vector<int> &A) {
  44.         if (A.empty()) {
  45.             return NULL;
  46.         }
  47.         return convert(A, 0, A.size() - 1);
  48.     }
  49. private:
  50.     TreeNode* convert(vector<int> &a, int ll, int rr) {
  51.         int mm = (ll + rr) / 2;
  52.         TreeNode* root = new TreeNode(a[mm]);
  53.         if (ll < mm) {
  54.             root->left = convert(a, ll, mm - 1);
  55.         }
  56.         if (rr > mm) {
  57.             root->right = convert(a, mm + 1, rr);
  58.         }
  59.         return root;
  60.     }
  61. };
复制代码
复杂度2:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 21:09:05 | 只看该作者
全局:
Climbing Stairs
题意:斐波那契。
解法:略。
代码:
  1. class Solution {
  2. public:
  3.     /**
  4.      * @param n: An integer
  5.      * @return: An integer
  6.      */
  7.     int climbStairs(int n) {
  8.         if (n < 2) {
  9.             return 1;
  10.         }
  11.         int a1, a2, a3;
  12.         a1 = a2 = 1;
  13.         int i;
  14.         for (i = 2; i <= n; ++i) {
  15.             a3 = a1 + a2;
  16.             a1 = a2;
  17.             a2 = a3;
  18.         }
  19.         return a3;
  20.     }
  21. };
复制代码
复杂度:时间O(N),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-26 21:41:29 | 只看该作者
全局:
Copy List with Random Pointer
题意:给定一个单链表,把它复制一份。特别之处在于每个节点还有一个随机指针,此指针指向链表中某个节点或者NULL。复制时务必让新链表保留同样的指向关系。
解法1:用哈希。哈希真乃丧心病狂的万能数据结构。
代码1:
  1. // O(n) solution with hashing
  2. /**
  3. * Definition for singly-linked list with a random pointer.
  4. * struct RandomListNode {
  5. *     int label;
  6. *     RandomListNode *next, *random;
  7. *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
  8. * };
  9. */
  10. typedef RandomListNode RLN;
  11. class Solution {
  12. public:
  13.     /**
  14.      * @param head: The head of linked list with a random pointer.
  15.      * @return: A new head of a deep copy of the list.
  16.      */
  17.     RLN *copyRandomList(RLN *head) {
  18.         if (head == NULL) {
  19.             return head;
  20.         }
  21.         int n, i;
  22.         RLN *p;
  23.         unordered_map<RLN *, int> um;
  24.         vector<RLN *> v;
  25.         
  26.         p = head;
  27.         n = 0;
  28.         while (p != NULL) {
  29.             um[p] = n++;
  30.             v.push_back(new RLN(p->label));
  31.             p = p->next;
  32.         }
  33.         
  34.         for (i = 0; i < n - 1; ++i) {
  35.             v[i]->next = v[i + 1];
  36.         }
  37.         p = head;
  38.         for (i = 0; i < n; ++i) {
  39.             v[i]->random = p->random != NULL ? v[um[p->random]] : NULL;
  40.             p = p->next;
  41.         }
  42.         
  43.         return v[0];
  44.     }
  45. };
复制代码
复杂度1:时间O(N),空间O(N)。

解法2:还是直接读代码吧。我这次终于独立写出来了,前两次都是bug层出不穷,虽然这次也不那么顺利,但对这种巧妙的思路逐渐理解。说穿了,也就是在这些链表的指针间进行各种轮换,看起来就跟变魔术一样,各种花式技巧。(就是为了面试欺负小朋友才出这种题)
代码2:
  1. // Whimsical solution
  2. /**
  3. * Definition for singly-linked list with a random pointer.
  4. * struct RandomListNode {
  5. *     int label;
  6. *     RandomListNode *next, *random;
  7. *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12.     /**
  13.      * @param head: The head of linked list with a random pointer.
  14.      * @return: A new head of a deep copy of the list.
  15.      */
  16.     RandomListNode *copyRandomList(RandomListNode *head) {
  17.         if (head == NULL) {
  18.             return head;
  19.         }
  20.         
  21.         RandomListNode *p, *q;
  22.         RandomListNode *h;
  23.         
  24.         p = head;
  25.         while (p != NULL) {
  26.             q = p->random;
  27.             p->random = new RandomListNode(p->label);
  28.             p->random->next = q;
  29.             
  30.             p = p->next;
  31.         }
  32.         
  33.         p = head;
  34.         while (p != NULL) {
  35.             q = p->random;
  36.             q->random = q->next ? q->next->random : NULL;
  37.             
  38.             p = p->next;
  39.         }
  40.         h = head->random;
  41.         p = head;
  42.         while (p != NULL) {
  43.             q = p->random;
  44.             p->random = q->next;
  45.             q->next = p->next ? p->next->random : NULL;
  46.             
  47.             p = p->next;
  48.         }
  49.         return h;
  50.     }
  51. };
复制代码
复杂度2:时间O(N),空间O(1),脑细胞O(你妹)。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表