LeeCode刷题总结(二)
LeeCode刷题总结(二)
前言
用leecode题目练手,练习编码的感觉。先从简单题开始,刷完后和知识点结合总结。
先刷简单题,对遇到的问题类型和不知道的知识点先列举。有空闲时间继续归类到《算法总结》。
经过LeeCode刷题总结(一)的c++语法和基本数据结构的掌握后,对简单题总的算法举例总结。
c++基本容器数据结构中使用最多的vector、string、TreeNode、ListNode,基本操作需要掌握。
递推
由前几项循环递推出第n项
//#118 杨辉三角 #119杨辉三角||
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> ans;
int i=0;
while(i++<numRows){
vector<int> Now(i,1);
if(i>2){
for(int j=1;j<i-1;j++)Now[j]= ans[i-2][j-1]+ans[i-2][j];
}ans.push_back(Now);
}
return ans;
}
};
递归
算f(n)规模的结果需要使用f(n-1)的结果
n的前几项有固定结果为初始值
计算机实现利用的是栈空间
//#38 外观数列
//求解n的问题要先求解n-1的问题。
//递归代码最神的地方, 一个循环可以展现出n个嵌套for循环的作用, 可以好好体会
class Solution {
public:
string countAndSay(int n) {
if(n==1) return "1";//1、初始条件,n==1
string ans = countAndSay(n-1);//2、递归函数n=f(n-1)
//3、已知n的返回值ans,来求解n+1的返回值now,n从初始条件1开始
//注意为什么是求解n+1的问题,n从1开始?因为递归的入参是n-1,最后的返回结果是求解n
string now;
int len = ans.length();
int j=0;//记录下标
for(int i=1;i<len+1;i++){
//最后一个元素要单独处理
if((ans[j]!=ans[i])||(i==len)){
//now += to_string(i-j)+ans[j]; //运算效率低很多
now.push_back(i-j+'0');
now.push_back(ans[j]);
j=i;
}
}
return now;
}
};
#100 相同的树;#101 对称二叉树;#104 二叉树的最大深度;#108 将有序数组转换为二叉搜索树;#110 平衡二叉树;#104 二叉树的最大深度;
**这些简单的二叉树问题无一例外,转换成本节点和左右子节点的递归运算**
动态规划
每次保存的值都在循环滚动
Dp本质还是迭代,总要有一个迭代的初值。正向迭代不是递归
//#70 爬楼梯 最简单的动态规划
class Solution {
public:
int climbStairs(int n) {
if(n<3)return n;
int i1=1;
int i2=2;
int temp;
for(int i=3;i<=n;i++){
temp=i1+i2;
i1=i2;
i2=temp;
}
return i2;
}
};
/*
递推超时,必须转动态规划怎么转?
动态规划是值都在变化,不一定是递归.3个值都在滚动相加。
递归从后往前推,一直到n=1/n=2,之前的子集求解多遍,
动态规划从前往后推,从n=1/n=2累计,保存每次的总数更新。
*/
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()==1)return 0;
int ans=0;
int min=prices[0];
for(int i=1;i<prices.size();i++){
ans=max(ans,prices[i]-min);
if(prices[i]<min)min=prices[i];
}
return ans;
}
};
/*
嵌套循环又超时...需要想优化的方法,
提示动态规划:第i天的最大收益=max(第i-1天的最大收益,前i-1天的值减最小值)
思路不够清晰的地方:第i-1天的最大收益,不用递归还是正推的DP
*/
双指针
ListNode的题目比较多,fast slow
//#141 判断链表是否有环,理解“这是因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合”是关键。
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==NULL)return false;
bool ans=false;
ListNode *fast=head;
ListNode *slow=head;
//一次需要判断两个步长
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
if(fast==slow){
ans =true;
break;
}
}
return ans;
}
};
/*
算法优化O(1),快慢指针指针相遇则有环。
理解一下:这是因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
*/

浙公网安备 33010602011771号