LintCode 解题记录 Array 17.6.5
来源:互联网 发布:中国投资咨询公司 知乎 编辑:程序博客网 时间:2024/06/08 20:11
周六做的几道题目,今天周一抽一个上午总结一下。
首先贴两张图,用来激励自己吧。
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 解题记录 Array 17.6.5
- LintCode 解题记录 17.5.22 (tag: Array)
- LintCode 解题记录 17.5.31(tag:Array)
- LintCode 解题记录 17.6.19~17.6.25
- LintCode 解题记录17.6.26 ~ 17.7.2
- LintCode 解题记录 17.10.5 递归
- LintCode 解题记录17.4.27
- LintCode解题记录17.4.28
- LintCode解题记录 17.5.3
- LintCode 解题记录 2017.6.3
- LintCode 解题记录 7.11 ~ 7.16
- LintCode 解题记录 Matrix专题
- LintCode解题记录17.9.9
- LintCode解题记录-Catalan Number
- LintCode 解题记录17.10.21
- LintCode 解题记录 17.11.11
- LintCode解题记录17.8.9 字符串处理5
- LintCode 解题记录 17.5.15 (tag: 哈希表)
- 图片选择器--AndroidImagePicker
- ORACLE 12C 安装过程相关报错及解决方案
- 图片轮播--AndroidImageSlider
- android--自定义view
- 为什么不能直接在BroadCastReceiver中开一个线程执行耗时任务
- LintCode 解题记录 Array 17.6.5
- 更改nginx网站根目录
- ACM:F: ACM小组的成绩排名
- 自学Java之Java编程(XML Web服务)(020day)
- Linux 内核源码(kernel source)
- 位运算实现加减乘除
- 【MyEclipse】设置作者信息等
- python学习笔记2
- maven项目 tomcat启动时报错遇到的坑