爬楼梯

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

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. popupTheme和theme

    popupTheme是指toolBar中弹出的menu的Theme. 那么,如果想让ToolBar的文字是白色,如果你设置Toolbar的Theme是 "ThemeOverlay.AppCo ...

  2. Code Chef - Chef and Graph Queries

    传送门 题目大意 给定一个$n$个点$m$条边的无向图$(n,m\leq 200000)$. 有$q$每次询问$(q\leq 200000)$,每次给定一个区间$L,R$,求仅保留编号$\in[L,R ...

  3. CSS禁止鼠标事件---pointer-events:none

    pointer-events:none顾名思意,就是鼠标事件拜拜的意思.元素应用了该CSS属性,链接啊,点击啊什么的都变成了“浮云牌酱油”.

  4. NSDictionary 用法

    //Dictionary //不可变 //字典里面:是以键值对存放的 //字典存放顺序是无序的 //字典里面:value可以重复,但key不能重复 //字典里面:key一般用字符串表示,value可用 ...

  5. Poj 2602 Superlong sums(大数相加)

    一.Description The creators of a new programming language D++ have found out that whatever limit for ...

  6. 【转】Pro Android学习笔记(十一):了解Intent(中)

    Intent的构成 Intent可以带有action,data(由URI表达),extra data(key/value map,键值对),指定的类名(成为component name).一个inte ...

  7. 使用ceph命令提示handle_connect_reply connect got BADAUTHORIZER

    输入命令提示如下错误: [root@node1 ~]# rados -p testpool ls 2017-10-21 06:13:25.743045 7f8f89b6d700 0 -- 192.16 ...

  8. SpringMvc之参数绑定注解详解之三

    2. @RequestHeader.@CookieValue @RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上. 示例代码: 这是一个Request ...

  9. 不支持PowerShell 2.0版本(don't support PowerShell version 2.0. )

    在“程序包管理器控制台”使用命令“update-database”会提示:The Entity Framework Core Package Manager Console Tools don't s ...

  10. 没办法,SVD就讲的这么好

    2)奇异值: 下面谈谈奇异值分解.特征值分解是一个提取矩阵特征很不错的方法,但是它只是对方阵而言的,在现实的世界中,我们看到的大部分矩阵都不是方阵,比如说有N个学生,每个学生有M科成绩,这样形成的一个 ...