LintCode 解题记录 Array 17.6.5
2017-06-05 12:35
375 查看
周六做的几道题目,今天周一抽一个上午总结一下。
首先贴两张图,用来激励自己吧。
![](https://img-blog.csdn.net/20170605114941102?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzIxMDgzMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170605114958165?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzIxMDgzMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
LintCode Combinations
给定两个数n和k,返回1~n中的任取k个数的所有组合。
dfs+回溯。难度一般。
LintCode Continuous Subarray Sum
返回最大子序列和的beginIndex和endIndex。
思路和最大子序列和一样,用两个指针记录最大和的开始和目前的位置。
LintCode Find Peak Element
Challenge:时间复杂度O(logn)
一看到O(logn)多半是和二分有关了。这道题可以用画图来很直观的理解。题目给的条件很有用。
贴代码:
LintCode Find the Duplicate Number
给定一个大小为n+1的数组,其中所有的数都在1~n之间,已知有且有一个数重复,问这个重复的数是多少。要求:1.不能改变原数组(不能用排序) 2.空间复杂度为O(1)(不能用Hash) 3.时间复杂度小于O(n^2)(不能用Brute-force)
第一种方法:1.O(nlogn) 二分搜索法
由于所有的数都是在1~n之间,那么对于数n/2,如果该数组中小于等于该数的次数大于n/2,则说明重复的数在1~n/2之间,否则就在n/2+1~n之间。所以时间复杂度是O(nlogn)。
代码:
第二种方法:O(n) Robert Floyd 算法
该算法常用于判断给定链表是否有环、以及求环的起点、以及求环的长度。贴一个写的不错的博客:
Robert Floyd Algorithm
其实这个算法自己画图稍微写几个公式就能理解了,关于此算法的应用有 Linked List Cycle + Linked List CycleII(直接在LintCode里搜索就能找到这两题)
那么本题用了这样的一个映射:index -> val。由于有重复的元素那么一定存在index1 != index2 但是 val1 == val2。那么x_n = f(x_n-1)按照这样的关系顺下去,最终环的起点就是要找的重复值。
代码:
总结:
1.温故而知新,尝回来看看,看看做过的题,在思考提升一下。
2.掌握 Robert Floyd判断环的方法,重要,面试常考。
首先贴两张图,用来激励自己吧。
LintCode Combinations
给定两个数n和k,返回1~n中的任取k个数的所有组合。
dfs+回溯。难度一般。
vector<vector<int> > combine(int n, int k) { // write your code here vector<vector<int>> ret; vector<int> tmp; int cnt = 0; if (n <= 0) return ret; for (int i = 1; i <= n; i++) { dfs(ret, tmp, cnt, i, n, k); } return ret; } void dfs(vector<vector<int>> &ret, vector<int> tmp, int cnt, int idx, int n, int k) { cnt++; tmp.push_back(idx); if (cnt == k) { ret.push_back(tmp); return; } for (int i = idx+1; i <= n; i++) { dfs(ret, tmp, cnt, i, n, k); } }
LintCode Continuous Subarray Sum
返回最大子序列和的beginIndex和endIndex。
思路和最大子序列和一样,用两个指针记录最大和的开始和目前的位置。
vector<int> continuousSubarraySum(vector<int>& A) { // Write your code here vector<int> ret(2, 0); vector<int> tmp; int sum = 0, ans = INT_MIN; for (int i = 0; i < A.size(); i++) { sum += A[i]; tmp.push_back(i); if (sum > ans) { ans = sum; ret[0] = tmp[0]; ret[1] = tmp[tmp.size()-1]; } if (sum < 0) { sum = 0; tmp.clear(); } } return ret; }
LintCode Find Peak Element
Challenge:时间复杂度O(logn)
一看到O(logn)多半是和二分有关了。这道题可以用画图来很直观的理解。题目给的条件很有用。
贴代码:
int findPeak(vector<int> A) { // write your code here int left = 1, right = A.size()-2; int mid = 0; while (left < right) { mid = (left+right) >> 1; if (A[mid] < A[mid+1]) left = mid+1; else if (A[mid] < A[mid-1]) right = mid-1; else return mid; } return left; }
LintCode Find the Duplicate Number
给定一个大小为n+1的数组,其中所有的数都在1~n之间,已知有且有一个数重复,问这个重复的数是多少。要求:1.不能改变原数组(不能用排序) 2.空间复杂度为O(1)(不能用Hash) 3.时间复杂度小于O(n^2)(不能用Brute-force)
第一种方法:1.O(nlogn) 二分搜索法
由于所有的数都是在1~n之间,那么对于数n/2,如果该数组中小于等于该数的次数大于n/2,则说明重复的数在1~n/2之间,否则就在n/2+1~n之间。所以时间复杂度是O(nlogn)。
代码:
int findDuplicate(vector<int>& nums) { // Write your code here int min = 1, max = nums.size()-1; int cnt = 0; while (min < max) { int mid = (min+max) >> 1; cnt = 0; for (int i = 0; i < nums.size(); i++) { if (nums[i] <= mid) cnt++; } if (cnt <= mid) min = mid+1; else max = mid; } return min; }
第二种方法:O(n) Robert Floyd 算法
该算法常用于判断给定链表是否有环、以及求环的起点、以及求环的长度。贴一个写的不错的博客:
Robert Floyd Algorithm
其实这个算法自己画图稍微写几个公式就能理解了,关于此算法的应用有 Linked List Cycle + Linked List CycleII(直接在LintCode里搜索就能找到这两题)
那么本题用了这样的一个映射:index -> val。由于有重复的元素那么一定存在index1 != index2 但是 val1 == val2。那么x_n = f(x_n-1)按照这样的关系顺下去,最终环的起点就是要找的重复值。
代码:
int findDuplicate(vector<int>& nums) { // Write your code here int slow, fast, t; slow = fast = t = 0; while (true) { slow = nums[slow]; fast = nums[nums[fast]]; if (slow == fast) break; } while (true) { slow = nums[slow]; t = nums[t]; if (slow == t) break; } return slow; }
总结:
1.温故而知新,尝回来看看,看看做过的题,在思考提升一下。
2.掌握 Robert Floyd判断环的方法,重要,面试常考。
相关文章推荐
- LintCode 解题记录17.6.26 ~ 17.7.2
- LintCode 解题记录 17.5.8 (tag:二叉树)
- LintCode 解题记录17.8.4 字符串处理2
- LintCode 解题记录 2017.6.3
- LintCode 解题记录17.5.10(tag:线段树)
- LintCode 解题记录 17.5.19 (tag: Hash表2)
- LintCode解题记录 动态规划专题 Part1 17.11.4
- LintCode 解题记录 17.8.30 两个指针
- LintCode解题记录17.8.9 字符串处理5
- LintCode 解题记录17.8.19 字符串处理6
- LintCode解题记录 17.5.3
- lintcode-medium-Find Minimum in Rotated Sorted Array
- Lintcode: Implement Queue by Stacks 解题报告
- LINTCODE——Folding Array
- 二、lintcode刷题记录--二叉树的路径和
- LintCode解题笔记 - 在O(1)时间复杂度删除链表节点
- LintCode Merge Sorted Array 合并排序数组
- lintcode/leetcode由易至难第4题:Array Partition I
- Lintcode: Subarray Sum 解题报告
- Google/LintCode:H-Median of two Sorted Array