LeetCode初级算法训练-动态规划(攻克中...)

简介

上一篇 : 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) 的解法,尝试使用更为精妙的分治法求解。

你可能感兴趣的:(LeetCode训练,Java)