leetcode记录 31-60
2016-06-13 10:35
495 查看
31 Next Permutation
STL源码剖析中就有这道题的思路32 longest valid parentheses (hard)
思路1:用stack实现。当i为左括号时,将i入栈。如果i为右括号时:栈顶元素对应的s为左括号,记录accout=i-stack.top();如果为左括号,则讲i入栈思路2:动态规划
初始化:dp[i]=0 i=0-len-1
从i=len-2开始 if(dp[i]==’(’ && i+dp[i+1]+1
int longestValidParentheses(string s) { int len = s.length(); if(len<2) return 0; int max = 0; int *dp = new int[len]; for(int k = 0;k<len;k++)//把辅助数组清空,存储为0 dp[k] = 0; for(int i = len-2;i>=0;i--) { if(s[i] == '(')//只对左括号处理,右括号在数组中存储为0 { int j = i+1+dp[i+1];//计算与当前左括号匹配的右括号的位置。可能存在也可能不存在 if(j<len && s[j] == ')')//确保位置不能越界 { dp[i] = dp[i+1] + 2;//找到了相匹配的右括号,当前数组中存储的最长长度是它后一个位置加2,后一个位置可能存储长度是0 if(j+1<len)//这是连接两个子匹配的关键步骤 dp[i] += dp[j+1];//在j的后面可能已经存在连续的匹配,要记得加上。dp[j+1]存储了以j+1开始的匹配 } if(dp[i]>max) max = dp[i];//更新最长长度 } } return max; }
33 search in rotated sorted array(hard)
这道题剑指offer出现过类似的题目,这道题是个简化的版本,不考虑元素存在重复的情况思路,用二值查找法
int search(vector<int>&A,int target) { int n=A.size(); int low=0; int high=n-1; while(low<=high){ int mid=low+(high-low)/2; if(A[mid]==target)return mid; if(A[mid]<A[high]) { if(A[mid]<target && A[high]>=target ) low=mid+1; else high=mid-1; } else { if(A[mid]>target &&A[low]<=target) high=mid-1; else low=mid+1; } } return -1; }
34 Search for a Range(medium)
在一个排序的数组中,找到给点数在数组中一样的数的下标范围思路:用二分查找,与普通二分查找差异处在于 nums[mid]==target 并没有结束。而是要找到low于mid之间最前面出现的target下标,找到high与mid之间最后面出现的target下标
//low int tmplow=low,tmphigh=mid-1,tmpmid; while(tmplow<=tmphigh) { tmpmid=(tmplow+tmphigh)/2; if(nums[tmpmid]==target) tmphigh=tmpmid-1; else tmplow=tmpmid+1; } result[0]=tmplow; //high tmplow=mid+1; tmphigh=high; while(tmplow<=tmphigh) { tmpmid=(tmplow+tmphigh)/2; if(nums[tmpmid]==target) tmplow=tmpmid+1; else tmphigh=tmpmid-1; } result[1]=tmphigh;
35 search insert position
在常规的二分查找的基础上,增加以下的代码即可if(nums[mid]>target) { if(mid==0) return 0; else return mid; } else return 4000 mid+1;
36 valid Sudoku
这道题是简单的,只要在3个条件下判断即可(3*3的正方形填充的数字是否要重复的元素,同理去判断每行,每列)只要有重复的元素出现,则返回false37 sudoku solver (hard)
这道题采用回溯法。每个格子没有存数,则每尝试一个数,先判断是否符合条件(检查每行每列,3*3元素是否存在跟填入的数相等的),符合条件,则进行下一个元素。。。。如果下一个元素返回false,当前元素再尝试一个新值38 count and say (easy)
这道题在弄懂题目的含义以后,还是很简单的。就是一种新的理解读数方式。讲每个数独立看待,如果有n个一样的数组digit连续出现则用ndigit表示。1—>11 11—>21 111->3139 combination sum
这道题的思想就是回溯的思想,这种思想在leetcode前面的题目出现过。基本思路进行下一层的遍历。。。返回到当层时,变量要恢复到以前的状态40 combination sum II
这一题在前一题的基础要多一些考虑。要考虑多个重复的数字的情况下,要如何组合。多个重复的数字为number,重复k次,则要考虑加入1-k次number的结果41 first missing positive (hard)
这道题的思路就是,通过交换实现,每个数字要对应于一位置。数字i存放在位置i-1,对于不符合条件的数字进行对换。最后,通过一次遍历,不满足条件nums[i]!=i+1,return i+1;这种解题思路,很多题目中都可以运用的到的
42 trapping rain water (hard)
思路:先找到最大值。然后从两端向中心的最大值遍历。在遍历过程中,每个柱子与遍历的目前最大值比较,如果小于它,面积加上两者之间的差值,如果大于它,则更新目前的最大值43 multiply (medium)
这道题就是大数相乘利用我们平时进行乘法的思想运算,从两个数的最低位进行乘法,乘法的结果要加上上次的进位
string multiply(string num1, string num2) { if (!num1.compare("0") || !num2.compare("0")) return "0"; string num; int len1=num1.length(); int len2=num2.length(); num.resize(len1+len2); int addon=0; for(int i=0; i<len1+len2; i++) { num[i]='0'; } for(int i=len1-1; i>=0; i--) { addon=0; for(int j=len2-1; j>=0; j--) { int tmp=num[i+j+1]-'0'+(num1[i]-'0')*(num2[j]-'0')+addon; addon=tmp/10; num[i+j+1]=tmp%10+'0'; } num[i]+=addon; } if(num[0]=='0')//只可能最高位为0 { num.erase(num.begin()); } return num; }
44wildcard matching (hard)
45 jump game II(hard)
比较目前能够到达的最远位置,到达最远位置后,要更新step,即++step,每次遍历更新增加一步能够到达的最远位置int jump(vector<int>& nums) { int n=nums.size(); if(n<=1) return 0; int step = 0; int curMax = 0; int curRch = 0; for(int i = 0; i < n; i ++) { if(curRch < i) { step ++; curRch = curMax; } curMax = max(curMax, nums[i]+i); } return step; }
46 permutations (medium)
就是STL中的思路47 permutations II (medium)
与上题一样48rotate image(medium)
i=1:n/2j=1:(n+1)/2
旋转的规律:(i,j)–>(n-1-j,i)
(n-1-j,i)–>(n-1-i,n-1-j)
(n-1-i,n-1-j)–>(j,n-1-i)
(j,n-1-i)–>(i,j)
49 Group anagrams (medium) 看看
用mapmap<string, vector<string>> hashMap; for(auto &v : strs) { string tmp(v); sort(tmp.begin(), tmp.end()); hashMap[tmp].push_back(v); } vector<vector<string>> result(hashMap.size()); int k = 0; for(auto it = hashMap.begin(); it != hashMap.end(); ++it, ++k) { result[k].swap(it->second); sort(result[k].begin(), result[k].end()); } return result;
50 pow(x,n) (medium)
用递归思想,result=pow(x,n/2) result=result^2; n为奇数 result=result*x 偶数 result=result进行运算,需要考虑的特殊情况。x为0,1,-1. n为0. n<0,尤其为INT_MIN。因为负数可以比正数多表示一个数,所有表示为pow(INT_MAX)*x
51 # N-Queens (hard)
用一个大小为N的数组,存储每行Q的位置最后遍历到row==N时,将结果存入到vector中
判断是否符合条件
bool check(int row, int* place) { for (int i = 0; i < row; ++i) { int diff = abs(place[i] - place[row]); if (diff == 0 || diff == row - i) return false; } return true; }
52 N-Queens II (hard)
与上一题类似53 Maximum subarray (medium)
这道题可以用贪心算法的思想,tempsum与maxvalue比较,如果大于则更新maxvalue。如果 tempsum<0,则令tempsum=0. 最后返回maxvalue54 spiral Matrix (medium)
这道题剑指offer中也有一样的题目。思路就是每次进行循环就是输出了2行2列的矩阵。用一个i表示进行第几次循环,结束条件也就清楚了一般情况下,一次循环可分割为4次操作。但是要考虑特殊情况。进行一次,两次,三次情况
vector<int> spiralOrder(vector<vector<int>>& matrix) { vector<int> result; int m=matrix.size(); if(m==0) return result; int n=matrix[0].size(); if(n==0) return result; int i=0; while (m-2*i>0 && n-2*i>0) { for (int j=i;j<n-i;++j) { result.push_back(matrix[i][j]); } for (int j=i+1;j<m-i;++j) { result.push_back(matrix[j][n-i-1]); } if (m-i-1>i) { for (int j=n-i-2;j>=i;--j) { result.push_back(matrix[m-i-1][j]); } } if (i!=n-i-1) {for (int j=m-i-2;j>i;--j) { result.push_back(matrix[j][i]); } } ++i; } return result; }
55 Jump Game (medium)
这道题采用贪心思想。从头开始遍历。如果maxstep==0,return false maxstep=–maxstep>nums[i] ?maxstep, nums[i];56 merge intervals (hard)
先对vector根据start大小进行排序,排序结束后,进行合并57 insert interval (hard)
一共分三种情况,插入的位置在头部,尾部,中间位置中间位置的情况要找到插入的地方,要确定pre,last坐标
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) { int len=intervals.size(); vector<Interval> result; if(len==0) { result.push_back(newInterval); return result; } if(newInterval.end<=intervals[0].end) { if (newInterval.end>=intervals[0].start) { intervals[0].start=min(intervals[0].start,newInterval.start); } else { intervals.insert(intervals.begin(),newInterval); } return intervals; } if (newInterval.start>=intervals[len-1].start) { if (newInterval.start<=intervals[len-1].end) { intervals[len-1].end=max(intervals[len-1].end,newInterval.end); } else { intervals.push_back(newInterval); } return intervals; } int pre=-1; int flag=0; for(int i=0;i<len;++i)//确定pre的位置 { if(intervals[i].end<newInterval.start) { pre=i; result.push_back(intervals[i]); } else break; } int last=pre; int i; for(i=pre+1;i<len;++i)//确定last位置 { if(intervals[i].start<=newInterval.end) b614 last=i; else break; } if (pre!=last) { newInterval.start=min(intervals[pre+1].start,newInterval.start); newInterval.end=max(intervals[last].end,newInterval.end); } result.push_back(newInterval); for(i=last+1;i<len;++i) result.push_back(intervals[i]); return result; }
58 length of last word (easy)
这道题很简单,从后面往前遍历。先找到第一个非空格的位置,再接着找到空格的位置即可59 spiral matrix II (medium)
这道题与54题类似,可以参照那一题的思路进行60 permutation sequence (medium)
假设有n个元素,第k个permutation是a1, a2, a3, ….. …, an那么这里,我们把a1去掉,那么剩下的permutation为
a2, a3, …. …. an, 共计n-1个元素。 n-1个元素共有(n-1)!个排列,那么这里就可以知道
设变量K1 = k
a1 = K1 / (n-1)!// 第一位的选择下标
同理,a2的值可以推导为
K2 = K1 % (n-1)!
a2 = K2 / (n-2)!
。。。。。
K(n-1) = K(n-2) /2!
a(n-1) = K(n-1) / 1!
an = K(n-1)
string getPermutation(int n, int k) { int sum=1; string str="123456789"; for(int i=1;i<=n;i++) sum=sum*i; k--; string r=""; for(int i=n;i>=1;i--) { sum=sum/i; int pos=k/sum; r+=str[pos]; k=k%sum; str.erase(pos,1); } return r; }
相关文章推荐
- python以post方式登录csdn网站,并以cookie方式访问个人信息
- 客户端和服务器端的区别
- Android源码适配器模式---Activity类结构
- Jsp中EL表达式
- Mysql最快清空数据库表的SQL语句
- leetcode 88. Merge Sorted Array
- Android 中ViewPager 实现banner无限轮播效果
- 第5章 什么是价值观假设和描述性假设
- 关于SpringMVC返回json数据的三种方式
- Web Tours自带示例网站无法打开的解决方案
- Chapter 4. 聚合函数、字符串函数、类型转换函数、时间日期函数
- Android 三轴绘制实时加速度曲线
- 使用CodeDOM实现代码生成及动态编译
- 几台电脑同时使用一个无线路由器上网,外部ip相同,各个电脑内部ip不同,路由器如何区分某个数据包是发给某个电脑的?
- Java RMI 框架(远程方法调用)
- 浅析RxJava处理复杂表单验证问题的方法
- Halcon图像预处理常用函数
- 用于分隔字符串的strtok()函数
- 使用Junit出现Type mismatch: cannot convert from Test to Annotation
- 使用Junit出现Type mismatch: cannot convert from Test to Annotation