上一篇 : LeetCode初级算法训练-排序和搜索
下一篇 : LeetCode初级算法训练-设计问题
本来想重初中级和企业面试算法开始的,但是最后还是选择从基础的开始,因为我们并不是为了刷题而刷题,而是在刷题过程中锻炼一种算法思维,在大量的训练之后形成一种对算法的独特见解,培养那种对算法的的敏感度,看到题目,大脑中可以浮现一个解题蓝图,而且从初级开始慢慢建立信心,而且这也是在为后边复杂算法的解题思路打基础。
LeetCode初级算法简介
如果你也想训练自己的算法思维,也可以加入我,从初级算法开始,开启你的算法之旅:初级算法。
自己的一些思考:不要在看完题目后直接就看答案,然后去背题,这样行成的算法记忆是不牢固的,一定要有自己的思考;而且不要一开始就在IDEA上边去写,一定试着自己在leetCode提供的白板上边写一遍最后在放到IDEA上边去执行看有什么问题,以便巩固你的基础API的使用和熟练度;还有一点就是大胆些,不是面试我们试错成本低,尽可能把我们的想法融入到代码中
因篇幅问题,博客中只列出示例和自己的解题答案,详细可以直接点击题目查看。
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
动态规划的思想:爬楼梯的最后一步只有两种情况一种是走一步,一种是走两步,f(x) = f(x - 1) + f(x -2),而且我们只要知道了第一层和第二层的方法数我们就可以计算出地n层的。
自己的第一想法是递归,但是超时了,n= 45时耗时4.638s,相当慢。
class Solution {
public int climbStairs(int n) {
if(n == 1) return 1;
if(n == 2) return 2;
return climbStairs(n - 1) + climbStairs(n - 2);
}
}
递归不行就换迭代,用for循环来实现。
class Solution {
public int climbStairs(int n) {
if(n == 1) return 1;
if(n == 2) return 2;
int stepNMinus1 = 1;
int stepNMinus2 = 2;
for(int i = 3 ; i <= n; i++){
int t = stepNMinus1;
stepNMinus1 = stepNMinus2;
stepNMinus2 = t + stepNMinus2;
}
return stepNMinus2;
}
}
45 / 45 个通过测试用例
状态:通过
执行用时:0 ms
内存消耗:36.6 MB
其实还可以进一步优化,使用矩阵快速幂或者Benets Fomula公式计算,但是这两个涉及到矩阵的计算,后期补一下这块,高数在学一遍,,,,,太难了。
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
我们只需要考虑如果我今天卖掉赚多少钱,价格更低的时候我会更新之前的购买的最小值,等到第二天的时候再卖掉,每次和上一天卖出的最高盈利比较,并替换盈利最大值。最后比较晚的最大值就是利润的最大值。
这是非常理想的购买股票状态,真正的股票你是不可能从未来看过去要买哪个不该买那个,买到历史最低点的。
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length == 0) return 0;
int low = prices[0];
int maxProfit = 0;
for(int i = 1; i < prices.length; i ++){
maxProfit = prices[i] - low > maxProfit ? prices[i] - low : maxProfit;
if(prices[i] < low){
low = prices[i];
}
}
return maxProfit;
}
}
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。