爬楼梯

第一想法自然是递归,而且爬楼梯很明显是一个斐波拉切数列,所以就有了以下代码:

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初级算法(动态规划+设计问题篇)的更多相关文章

  1. LeetCode初级算法--动态规划01:爬楼梯

    LeetCode初级算法--动态规划01:爬楼梯 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  2. 算法练习LeetCode初级算法之设计问题

    打乱数组 不断的让第一个与后面随机选择的数交换 class Solution { private int[] nums; private int[] initnums; public Solution ...

  3. LeetCode探索初级算法 - 动态规划

    LeetCode探索初级算法 - 动态规划 今天在LeetCode上做了几个简单的动态规划的题目,也算是对动态规划有个基本的了解了.现在对动态规划这个算法做一个简单的总结. 什么是动态规划 动态规划英 ...

  4. LeetCode初级算法的Python实现--排序和搜索、设计问题、数学及其他

    LeetCode初级算法的Python实现--排序和搜索.设计问题.数学及其他 1.排序和搜索 class Solution(object): # 合并两个有序数组 def merge(self, n ...

  5. LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组)

    LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:h ...

  6. LeetCode初级算法--设计问题02:最小栈

    LeetCode初级算法--设计问题02:最小栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  7. LeetCode初级算法(数组)解答

    这里记录了LeetCode初级算法中数组的一些题目: 加一 本来想先转成整数,加1后再转回去:耽美想到测试的例子考虑到了这个方法的笨重,所以int类型超了最大范围65536,导致程序出错. class ...

  8. 【LeetCode算法】LeetCode初级算法——字符串

      在LeetCode初级算法的字符串专题中,共给出了九道题目,分别为:反转字符串,整数反转,字符串中的第一个唯一字符,有效的字母异位词,验证回文字符串,字符串转换整数,实现strStr(),报数,最 ...

  9. LeetCode初级算法之数组:48 旋转图像

    旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...

随机推荐

  1. FFmpeg内存操作(三)内存转码器

    相关博客列表 : FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析 FFMPEG内存操作(二)从内存中读取数及数据格式的转换 FFmpeg内存操作(三)内存转码器 本文 ...

  2. mci播放mp3

    1MIDI的播放---- 乐器数字化接口(MIDI)是由音乐界的一些大公司(包括生产电子音乐合成器的公司)制订的一项协议,后来被计算机产业所采用并成为多媒体音乐文件的标准格式.MIDI文件一般较小,对 ...

  3. Hough变换原理

    Hough变换原理 一.简单介绍 Hough变换是图像处理中从图像中识别几何形状的基本方法之一.Hough变换的基本原理在于利用点与线的对偶性,将原始图像空间的给定的曲线通过曲线表达形式变为参数空间的 ...

  4. android开发 MyEclipse下测试连接MySQL数据库

    1.首先要加载MySQL驱动包. 步骤:右击项目找到build path->configure build path->libraries——>add External JARs添加 ...

  5. Spring之2:Spring Bean动态注册、删除

    IoC容器的初始化包括BeanDefinition的Resource定位.载入和注册这三个基本的过程. 一.Resource定位.BeanDefinition的资源定位有resourceLoader通 ...

  6. Design:目录

    ylbtech-Design:目录 1.返回顶部 1. http://idesign.qq.com/#!index/feed 2. https://www.behance.net/ 3. 2.返回顶部 ...

  7. docker 部署服务时,node(结点)显示no such image

    1. 问题描述 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 9cn5x84lnmga getstartedlab_web.1 ...

  8. 【问题】Expandable数据集的定义的正确方法,TabActivity弃用替代,Gallery替代,imageswitcher

    Expandable 问题: http://www.cnblogs.com/xingyyy/p/3389611.html 扩展阅读:http://blog.csdn.net/lmj623565791/ ...

  9. [bzoj1568]李超线段树模板题(标志永久化)

    题意:要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. 解题关键:注意标 ...

  10. Learning Python 002 print() 和 input()

    Python print() 和 input() print()函数 print()函数可以向终端中输入指定的内容. 输出当个字符串 .py文件中,输入下面的代码,并保存: print('hello ...