您的位置:首页 > 其它

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的正方形填充的数字是否要重复的元素,同理去判断每行,每列)只要有重复的元素出现,则返回false

37 sudoku solver (hard)

这道题采用回溯法。每个格子没有存数,则每尝试一个数,先判断是否符合条件(检查每行每列,3*3元素是否存在跟填入的数相等的),符合条件,则进行下一个元素。。。。如果下一个元素返回false,当前元素再尝试一个新值

38 count and say (easy)

这道题在弄懂题目的含义以后,还是很简单的。就是一种新的理解读数方式。讲每个数独立看待,如果有n个一样的数组digit连续出现则用ndigit表示。1—>11 11—>21 111->31

39 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/2

j=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) 看看

用map

map<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. 最后返回maxvalue

54 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: