爬楼梯

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

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. nodejs 静态文件服务器

    https://cnodejs.org/topic/4f16442ccae1f4aa27001071 http://blog.csdn.net/zhangxin09/article/details/8 ...

  2. 洛谷 4178 Tree——点分治

    题目:https://www.luogu.org/problemnew/show/P4178 点分治.如果把每次的 dis 和 K-dis 都离散化,用树状数组找,是O(n*logn*logn),会T ...

  3. virtual judge(专题一 简单搜索 C)

    Description Farmer John has been informed of the location of a fugitive cow and wants to catch her i ...

  4. 我的SIP开发之路

    http://hi.baidu.com/ltlovelty/blog/item/837baf1ece7fc6f11ad57647.html 经过对SIP协议和开源协议栈快半年的研究,我现在终于有点入门 ...

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

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

  6. Mac搭建nginx+rtmp服务器

    nginx是非常优秀的开源服务器,用它来做hls或者rtmp流媒体服务器是非常不错的选择,本人在网上整理了安装流程,分享给大家并且作备忘. 一.安装Homebrow 已经安装了brow的可以直接跳过这 ...

  7. MS-SQL循环、随机数

    ---创建视图 create view myview as select re=rand() --自定义函数:取得指定范围的随机数 create function mydata( @a int, @b ...

  8. 关于request的几个字段值

    domain: localhost host: localhost:9000 url: /wechat/mynews action: WechatController.myNews path: /we ...

  9. 请定义一个宏,比较两个数的a、b的大小,不能使用大于、小于、if语句

    请定义一个宏,比较两个数的a.b的大小,不能使用大于.小于.if语句 方法一:    #define max(a,b) ((((long)((a)-(b)))&0x80000000)?(b): ...

  10. 杭电acm 1032题

    The Problem问题 Consider the following algorithm:考虑下面的算法: 1 2 3 4 5 6 input n print n if n = 1 then st ...