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

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

 
🔗
 楼主| zhuli19901106 2015-7-25 16:15:58 | 只看该作者
全局:
Assignment Operator Overloading (C++ Only)
题意:这题是针对C++的。给定一个含有动态分配数据的对象,请实现它的构造、析构和赋值。
解法:这题和算法无关,是考察语言特性。其实主要目的是要建立起内存管理的意识,要对内存泄漏、深拷贝、浅拷贝之类的概念心里有数。
代码:
  1. #include <cstring>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     char *m_pData;
  6.     Solution() {
  7.         this->m_pData = NULL;
  8.     }
  9.    
  10.     Solution(char *pData) {
  11.         this->m_pData = pData;
  12.     }
  13.    
  14.     ~Solution() {
  15.         delete m_pData;
  16.         m_pData = NULL;
  17.     }

  18.     // Implement an assignment operator
  19.     Solution &operator = (const Solution &object) {
  20.                 if (m_pData == object.m_pData) {
  21.             // No need to clone yourself
  22.                         return *this;
  23.                 }

  24.         if (m_pData != NULL) {
  25.             delete[] m_pData;
  26.             m_pData = NULL;
  27.         }
  28.         char *ptr = NULL;
  29.         if (object.m_pData != NULL) {
  30.                         int len = strlen(object.m_pData);
  31.             m_pData = new char[len + 1];
  32.             strcpy(m_pData, object.m_pData);
  33.         }
  34.         return *this;
  35.     }
  36. };
复制代码
复杂度:时间O(1),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 16:24:15 | 只看该作者
全局:
本帖最后由 zhuli19901106 于 2015-7-25 17:20 编辑

Triangle Count
题意:hard难度。给定一个数组,求其中可以组成三角形的三元组有多少个。
解法1:暴力枚举,这也能AC,看来lintcode真宽容。
代码1:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param S: A list of integers
  7.      * @return: An integer
  8.      */
  9.     int triangleCount(vector<int> &S) {
  10.         sort(S.begin(), S.end());
  11.         
  12.         int i, j, k;
  13.         int ans = 0;
  14.         int n = S.size();
  15.         
  16.         for (i = 0; i < n; ++i) {
  17.             for (j = i + 1; j < n; ++j) {
  18.                 for (k = j + 1; k < n && S[i] + S[j] > S[k]; ++k) {
  19.                     ++ans;
  20.                 }
  21.             }
  22.         }
  23.         return ans;
  24.     }
  25. };
复制代码
复杂度1:时间O(N^3),空间O(1)。

解法2:前两维枚举,第三维二分。那么这题的hard体现在哪儿呢。
代码2:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param S: A list of integers
  7.      * @return: An integer
  8.      */
  9.     int triangleCount(vector<int> &S) {
  10.         sort(S.begin(), S.end());
  11.         
  12.         int i, j, k;
  13.         int ans = 0;
  14.         int n = S.size();
  15.         
  16.         for (i = 0; i < n; ++i) {
  17.             for (j = i + 1; j < n; ++j) {
  18.                 k = lower_bound(S.begin() + j + 1, S.end(), S[i] + S[j]) - S.begin();
  19.                 ans += k - j - 1;
  20.             }
  21.         }
  22.         return ans;
  23.     }
  24. };
复制代码
复杂度2:时间O(N^2 * log(N))。空间可以O(1),如果二分自己手写的话,不过没必要那么钻牛角尖。

解法3:感谢stellari的提醒,我都没考虑还有O(N ^ 2)的做法,看来脑子又犯懒了。对于每个A{i},可以用两个指针j个k直接向前移,而不需要二分搜索。 这样总体复杂度是平方级别。
从运行时间可以看出三者的明显差距,所以轻敌是大忌啊。嘿嘿~
代码3:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param S: A list of integers
  7.      * @return: An integer
  8.      */
  9.     int triangleCount(vector<int> &S) {
  10.         sort(S.begin(), S.end());
  11.         
  12.         int i, j, k;
  13.         int ans = 0;
  14.         int n = S.size();
  15.         
  16.         for (i = 0; i < n; ++i) {
  17.             j = i + 1;
  18.             k = j + 1;
  19.             while (j < n - 1) {
  20.                 while (k < n && S[k] - S[j] < S[i]) {
  21.                     ++k;
  22.                 }
  23.                 ans += k - j - 1;
  24.                 ++j;
  25.             }
  26.         }
  27.         return ans;
  28.     }
  29. };
复制代码
复杂度3:时间O(N ^ 2),空间O(1)。

回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 16:38:26 | 只看该作者
全局:
Add Binary
题意:二进制大数加法,用字符串表示。
解法:面试中的热身题,所以不能出bug。不知道怎么写才能比较简洁。
代码:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param a a number
  7.      * @param b a number
  8.      * @return the result
  9.      */
  10.     string addBinary(string& a, string& b) {
  11.         if (a.length() < b.length()) {
  12.             return addBinary(b, a);
  13.         }
  14.         
  15.         reverse(a.begin(), a.end());
  16.         reverse(b.begin(), b.end());
  17.         
  18.         string s = "";
  19.         int al = a.length();
  20.         int bl = b.length();
  21.         int i;
  22.         for (i = 0; i < bl; ++i) {
  23.             s.push_back(a[i] + b[i] - '0');
  24.         }
  25.         for (i = bl; i < al; ++i) {
  26.             s.push_back(a[i]);
  27.         }
  28.         
  29.         int c = 0;
  30.         for (i = 0; i < al - 1; ++i) {
  31.             c = s[i] - '0' >> 1;
  32.             s[i] = (s[i] - '0' & 1) + '0';
  33.             s[i + 1] += c;
  34.         }
  35.         c = s[i] - '0' >> 1;
  36.         s[i] = (s[i] - '0' & 1) + '0';
  37.         if (c) {
  38.             s.push_back('1');
  39.         }
  40.         reverse(s.begin(), s.end());
  41.         
  42.         return s;
  43.     }
  44. };
复制代码
复杂度:时间O(N),空间O(1)。


回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 16:42:19 | 只看该作者
全局:
Convert Sorted Array to Binary Search Tree With Minimal Height
题意:把一个有序数组转化为二叉搜索树,要求高度最小。
解法:其实也就是转换成平衡树,所以对半分,递归求解。
代码:
  1. /**
  2. * Definition of TreeNode:
  3. * class TreeNode {
  4. * public:
  5. *     int val;
  6. *     TreeNode *left, *right;
  7. *     TreeNode(int val) {
  8. *         this->val = val;
  9. *         this->left = this->right = NULL;
  10. *     }
  11. * }
  12. */
  13. class Solution {
  14. public:
  15.     /**
  16.      * @param A: A sorted (increasing order) array
  17.      * @return: A tree node
  18.      */
  19.     TreeNode* sortedArrayToBST(vector<int> &A) {
  20.         if (A.empty()) {
  21.             return NULL;
  22.         }
  23.         return convert(A, 0, A.size() - 1);
  24.     }
  25. private:
  26.     TreeNode* convert(vector<int> &a, int ll, int rr) {
  27.         int mm = (ll + rr) / 2;
  28.         TreeNode* root = new TreeNode(a[mm]);
  29.         if (ll < mm) {
  30.             root->left = convert(a, ll, mm - 1);
  31.         }
  32.         if (rr > mm) {
  33.             root->right = convert(a, mm + 1, rr);
  34.         }
  35.         return root;
  36.     }
  37. };
复制代码
复杂度:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
stellari 2015-7-25 16:51:39 | 只看该作者
全局:
zhuli19901106 发表于 2015-7-25 16:24
Triangle Count
题意:hard难度。给定一个数组,求其中可以组成三角形的三元组有多少个。
解法1:暴力枚 ...

这个题有O(N^2)的解法,这应该就是体现Hard难度的地方了吧。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 17:02:16 | 只看该作者
全局:
本帖最后由 zhuli19901106 于 2015-7-25 17:22 编辑
stellari 发表于 2015-7-25 16:51
这个题有O(N^2)的解法,这应该就是体现Hard难度的地方了吧。

哦,还真有啊。容我再想想~~
已搞定,感谢提醒!

回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 17:37:40 | 只看该作者
全局:
Plus One
题意:大数加1
解法:注意存储方式是反过来的。
代码:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.      * @param digits a number represented as an array of digits
  7.      * @return the result
  8.      */
  9.     vector<int> plusOne(vector<int> &digits) {
  10.                 vector<int> &a = digits;
  11.                
  12.                 reverse(a.begin(), a.end());
  13.                 int i, n = a.size();
  14.                 int c = 0;
  15.                 a[0] += 1;
  16.                 for (i = 0; i < n; ++i) {
  17.                         a[i] += c;
  18.                         c = a[i] / 10;
  19.                         a[i] %= 10;
  20.                 }
  21.                 if (c) {
  22.                         a.push_back(c);
  23.                 }
  24.                 reverse(a.begin(), a.end());
  25.                 return a;
  26.     }
  27. };
复制代码
复杂度:时间O(N),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 17:41:41 | 只看该作者
全局:
Divide Two Integers
题意:给定两个整数,实现整数除法,但不能用*/%。注意判断溢出。
解法:既然不能用乘除模,那就加减位运算吧。
代码:
  1. #include <climits>
  2. using namespace std;

  3. typedef long long int LL;

  4. class Solution {
  5. public:
  6.     /**
  7.      * @param dividend the dividend
  8.      * @param divisor the divisor
  9.      * @return the result
  10.      */
  11.     int divide(int dividend, int divisor) {
  12.         LL f = 1;
  13.         LL a = dividend;
  14.         LL b = divisor;
  15.         LL base;
  16.         
  17.         if (a == 0) {
  18.             return 0;
  19.         }
  20.         
  21.         if (a < 0) {
  22.             a = -a;
  23.             f = -f;
  24.         }
  25.         if (b < 0) {
  26.             b = -b;
  27.             f = -f;
  28.         }
  29.         
  30.         LL b2;
  31.         base = b;
  32.         b2 = 1;
  33.         while ((base << 1) <= a) {
  34.             base <<= 1;
  35.             b2 <<= 1;
  36.         }
  37.         LL ans = 0;
  38.         while (base >= b) {
  39.             if (a >= base) {
  40.                 a -= base;
  41.                 ans += b2;
  42.             }
  43.             base >>= 1;
  44.             b2 >>= 1;
  45.         }
  46.         ans *= f;
  47.         if (ans < INT_MIN || ans > INT_MAX) {
  48.             ans = INT_MAX;
  49.         }
  50.         return ans;
  51.     }
  52. };
复制代码
复杂度:时间O(log(N)),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 17:48:36 | 只看该作者
全局:
Gray Code
题意:用代码生成N位的格雷码序列。
解法:考虑N位格雷码N-1位格雷码的关联。
代码:
  1. class Solution {
  2. public:
  3.     /**
  4.      * @param n a number
  5.      * @return Gray code
  6.      */
  7.     vector<int> grayCode(int n) {
  8.         vector<int> v;
  9.         v.push_back(0);
  10.         int i, j;
  11.         int b;
  12.         
  13.         b = 1;
  14.         for (i = 0; i < n; ++i) {
  15.             for (j = b - 1; j >= 0; --j) {
  16.                 v.push_back(b | v[j]);
  17.             }
  18.             b <<= 1;
  19.         }
  20.         return v;
  21.     }
  22. };
复制代码
复杂度:时间O(2 ^ N),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 17:56:04 | 只看该作者
全局:
Reverse Integer
题意:给定一个整数,按其十进制表示,把这个数反转。
解法:注意符号和溢出。
代码:
  1. #include <climits>
  2. using namespace std;

  3. typedef long long int LL;

  4. class Solution {
  5. public:
  6.     /**
  7.      * @param n the integer to be reversed
  8.      * @return the reversed integer
  9.      */
  10.     int reverseInteger(int n) {
  11.         if (n == 0) {
  12.             return 0;
  13.         }
  14.         
  15.         LL ans;
  16.         int sign = n > 0 ? 1 : -1;
  17.         
  18.         ans = 0;
  19.         if (n < 0) {
  20.             n = -n;
  21.         }
  22.         while (n != 0) {
  23.             ans = ans * 10 + n % 10;
  24.             n /= 10;
  25.         }
  26.         ans *= sign;
  27.         if (ans > INT_MAX || ans < INT_MIN) {
  28.             return 0;
  29.         }
  30.         return ans;
  31.     }
  32. };
复制代码
复杂度:时间O(log(N)),空间O(1)。
回复

使用道具 举报

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

本版积分规则

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