LeetCode初级算法(动态规划+设计问题篇)
爬楼梯
第一想法自然是递归,而且爬楼梯很明显是一个斐波拉切数列,所以就有了以下代码:
class Solution {
public:
int climbStairs(int n) {
if(n==0) return 0;
if(n==1) return 1;
if(n==2) return 2;
if(n>2)
{
return (climbStairs(n-1)+climbStairs(n-2));
}
}
};
但是在输入为44的时候提示超出时间限制了,仔细想想的确如此,反复递归、调用函数的开销还是挺大的。所以如果换成循环会不会好一点呢?
class Solution {
public:
int climbStairs(int n) {
if(n==0) return 0;
vector<int> res(n);
res[0]=1;
res[1]=2;
for(int i=2;i<n;i++)
{
res[i]=res[i-1]+res[i-2];
}
return res[n-1];
}
};
结果没有超时,用循环的开销还是可以的。
买卖股票的最佳时机
之前记得数组篇里写了买卖股票的最佳时机类似的题,但是这题却和那道题不太一样。这题要求的是当前的值和之前的最小值的差值为最大,所以如果输入的数据是递减的话,后面减去前面只会一直为负值所以最大李瑞为0。这里我们用buy来存储前面的最小值,用res来存储当前的最大利润,代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res=0;
int buy=INT_MAX;
for(int i=0;i<prices.size();i++)
{
buy=min(prices[i],buy);
res=max(res,prices[i]-buy);
}
return res;
}
};
最大子序和
由于涉及到连续和,所以觉得用循环来做应该还可以。想法就是把所有的和存储到一个容器里,然后简单排序一下取最大的就ok了,代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> a;
if(nums.size()==1) return nums[0];
for(int i=0;i<nums.size();i++)
{
int sum=nums[i];
a.push_back(sum);
for(int j=i+1;j<nums.size();j++)
{
sum+=nums[j];
a.push_back(sum);
}
}
sort(a.begin(),a.end());
return a[a.size()-1];
}
};
但是,果然还是由于输入量如果过大的话,会开销很大,所以超出时间限制了。所以换了思路,采用如下的代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int res=INT_MIN;
int curSum=0;
for(int i=0;i<nums.size();i++)
{
curSum=max(curSum+nums[i],nums[i]);
res=max(res,curSum);
}
return res;
}
};
打家劫舍
这道题的意思其实就是,一个数组,求 不取相邻的数 的和的最大值。下面是动态规划的解法:
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()<=1) return nums.empty()?0:nums[0];
vector<int> dp={nums[0],max(nums[0],nums[1])};
for(int i=2;i<nums.size();i++)
dp.push_back(max(nums[i]+dp[i-2],dp[i-1]));
return dp.back();
}
};
此外,还有另外一种思路,见大神的代码:
class Solution {
public:
int rob(vector<int>& nums) {
intfor(inti0;i<nums.size();i++)
{
if(i%2==0)
{
a+=nums[i];
a=max(a,b);
}
else
{
b+=nums[i];
b=max(a,b);
}
}
return max(a,b);
}
};
这段代码更容易理解,只是不知道是如何想出来的。
动态规划小结
感觉动态规划问题就是一定要注意前面计算的结果和即将计算结果之间的联系,妥善处理它们之间的表达式就会有正确的思路。感觉自己在这种问题上的思考深度还是不够,具有局限性,刷完初级算法后会专门来学习一下动态规划问题的解法。
Shuffle an Array
这道题思路很简单,但主要是考察几个函数之间的调换关系。比如需要创建爱你一个私有类来声明vec这个数组用于全局。见代码:
class Solution {
public:
Solution(vector<int> nums):vec(nums) {
}
/** Resets the array to its original configuration and return it. */
vector<int> reset() {
return vec;
}
/** Returns a random shuffling of the array. */
vector<int> shuffle() {
vector<int> res=vec;
for(int i=0;i<res.size();i++)
{
int pos =rand() % (res.size() - i);
swap(res[i], res[i+pos]);
}
return res;
}
private:
vector<int> vec;
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* vector<int> param_1 = obj.reset();
* vector<int> param_2 = obj.shuffle();
*/
最小栈
这道题觉得可以构造一个vector容器,然后利用vector的相关成员函数来解决,当时觉得题目既然叫"最小栈",呢必然是用其他的方式去实现栈的操作呀,所以自己的代码如下:
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
res.push_back(x);
}
void pop() {
res.pop_back();
}
int top() {
if(res.size()==0) return NULL;
return res.back();
}
int getMin() {
if(res.size()==0) return NULL;
vector<int> temp=res;
sort(temp.begin(),temp.end());
return temp[0];
}
private:
vector<int> res;
};
上面的代码我自己测了几个案例是可以的,但是在提交的时候却显示超出时间限制,简单的少了一眼大神的代码,发现是直接用stack来做的。。。可是如果stack能通过的话,vector怎么会通不过呢?先放上大神的代码,直接用stack的话比较好理解:
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
s1.push(x);
if(s2.empty()||x<=s2.top())
s2.push(x);
}
void pop() {
if(s1.top()==s2.top())
s2.pop();
s1.pop();
}
int top() {
return s1.top();
}
int getMin() {
return s2.top();
}
private:
stack<int> s1,s2;
};
在网上搜了一下,也有人用vector做出来了:
class MinStack {
public:
vector<int> allVec;
vector<int> minVec;
void push(int x) {
if (allVec.empty()) {
allVec.push_back(x);
minVec.push_back(x);
}
else {
if (x <= minVec[minVec.size() - 1]) {
minVec.push_back(x);
}
allVec.push_back(x);
}
}
void pop() {
if (allVec[allVec.size() - 1] == minVec[minVec.size() - 1])
minVec.erase(minVec.end() - 1);
allVec.erase(allVec.end() - 1);
}
int top() {
return allVec[allVec.size() - 1];
}
int getMin() {
return minVec[minVec.size() - 1];
}
};
他这样解的思路在于,设置里两个vector,一个是存储所有的元素,另一个是存储最小元素。首先看push(),如果为空就push进去;不为空就判断如果比minVec中最后一个元素要小,就放进minVec中、allVec是始终都要放得。再看pop(),如果allVec[allVec.size() - 1] == minVec[minVec.size() - 1]
,即如果要删除的元素是最小值的话,就必须将minVec最后一个元素也删掉,确保minVec中存储的都是有效的最小值;allVec直接将最后一个元素清除。top()则是返回allVec最后一个元素,getMin()是返回minVec的最后一个元素。和自己的代码作比较,感觉自己花了两个vector存储一样的数组并且当输入巨大的时候,数组复制一定耗费了大量的时间所以会导致超出时间限制。
但是不得不说,vector确实相较stack来说效率有点低。
LeetCode初级算法(动态规划+设计问题篇)的更多相关文章
- LeetCode初级算法--动态规划01:爬楼梯
LeetCode初级算法--动态规划01:爬楼梯 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- 算法练习LeetCode初级算法之设计问题
打乱数组 不断的让第一个与后面随机选择的数交换 class Solution { private int[] nums; private int[] initnums; public Solution ...
- LeetCode探索初级算法 - 动态规划
LeetCode探索初级算法 - 动态规划 今天在LeetCode上做了几个简单的动态规划的题目,也算是对动态规划有个基本的了解了.现在对动态规划这个算法做一个简单的总结. 什么是动态规划 动态规划英 ...
- LeetCode初级算法的Python实现--排序和搜索、设计问题、数学及其他
LeetCode初级算法的Python实现--排序和搜索.设计问题.数学及其他 1.排序和搜索 class Solution(object): # 合并两个有序数组 def merge(self, n ...
- LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组)
LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:h ...
- LeetCode初级算法--设计问题02:最小栈
LeetCode初级算法--设计问题02:最小栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- LeetCode初级算法(数组)解答
这里记录了LeetCode初级算法中数组的一些题目: 加一 本来想先转成整数,加1后再转回去:耽美想到测试的例子考虑到了这个方法的笨重,所以int类型超了最大范围65536,导致程序出错. class ...
- 【LeetCode算法】LeetCode初级算法——字符串
在LeetCode初级算法的字符串专题中,共给出了九道题目,分别为:反转字符串,整数反转,字符串中的第一个唯一字符,有效的字母异位词,验证回文字符串,字符串转换整数,实现strStr(),报数,最 ...
- LeetCode初级算法之数组:48 旋转图像
旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...
随机推荐
- bzoj 2434: 阿狸的打字机 fail树+离线树状数组
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...
- Operating System-Kickoff:什么是操作系统&&操作系统的核心概念
接下来会写一系列Operating System(操作系统)的文章,今天先开个头.本文主要内容: 什么是操作系统 操作系统的核心概念 程序=数据结构+算法 一.什么是操作系统 1.1 操作系统是对硬件 ...
- 洛谷 1351 联合权值——树形dp
题目:https://www.luogu.org/problemnew/show/P1351 对拍了一下,才发现自己漏掉了那种拐弯的情况. #include<iostream> #incl ...
- import module, from module import funtion区别
import module与from module import funtion区别: import module导入模块后你需要使用module.function()来调用一个函数 from mod ...
- 自定义echart tooltip格式
formatter: function (tipData) { return tipData[0].name + '</br>' + '<span style="displ ...
- Python-requests取消SSL验证的警告InsecureRequestWarning解决办法
使用requests模块请求一个证书无效的网站的话会直接报错 可以设置verify参数为False解决这个问题 # -*- coding:utf-8 -*- __author__ = "Mu ...
- 基于Docker部署私有npm
NPM作为前端最cool及最烂的包管理器,它解决困扰前端工程化发展中代码模块管理的大问题.但是随着业务需求的发展,我们的代码从以前的单项目复用,延伸出了多项目复用的需求.本来项目之间代码复用管理的情景 ...
- Java进阶之美文共享
2.在Java中如何避免"!=null"式的判空语句? 3.Java问答:终极父类(3) Java问答:终极父类(下) Java问答:终极父类(上) 内存不足:杀死进程还是牺牲 ...
- Flask09 原始输出、转义、XSS攻击、过滤器???
1 怎么在jinja模板中原始输出模板语法 1.1 用双引号引起来后放到 {{ }} 中 例如 {{ "{{}}" }} 输出 1.2 利用raw 例如 {% raw %} {% ...
- AngularJs(Part 9)--AngularJS 表单
AngularJS 表单 AngularJS使用了MVX的结构,我们可以是传统的表单更加强大.比如过去我们得自己写一大堆验证,比过过去我们得自己转换用户的输入, 现在这些工作全部可以交给Ang ...