美文网首页
LeetCode #70 #746 #55 #45 2018-0

LeetCode #70 #746 #55 #45 2018-0

作者: 40巨盗 | 来源:发表于2018-08-22 21:55 被阅读0次

    Part 2 – Sequence Dynamic Programming

    这类题目是动态规划当中中等难度的,递推量相对固定,但递推式需要根据题目的要求做出相应的变化。同样当我们明确了4个主要元素,问题就会迎刃而解。
    1)确定递推量。res[i]一般表示第i个位置/数字/字母的状态;
    2)推导递推式。一般可以研究res[i]之前的res[j]对res[i]的影响;
    3)计算初始条件。res[0]/res[n - 1];
    4)考虑存储历史信息的空间维度(可选)。一般就是一维空间,不可优化。

    70. Climbing Stairs

    https://leetcode.com/problems/climbing-stairs/description/

    res[i]表示前i个位置跳到第i个位置的方案总数,递推式res[i] = res[i - 1] + res[i - 2],典型的Fabonacci数列。初始化res[0] = 1, res[1] = 1,递推得到结果。
    代码如下:

    class Solution:
        def climbStairs(self, n):
            """
            :type n: int
            :rtype: int
            """
            if n == 1:
                return 1
            f0 = 1
            f1 = 1
            for i in range(1, n):
                f2 = f0 + f1
                f0, f1 = f1, f2
            return f2
    

    746. Min Cost Climbing Stairs

    https://leetcode.com/problems/min-cost-climbing-stairs/description/

    cost[i]表示通过当前位置需要的最小cost数值,递推式cost[i] = min(cost[i-1], cost[i-2]) + cost[i],注意边界条件,注意最后可选下标为-1或者-2两种情况即可。
    代码如下:

    class Solution:
        def minCostClimbingStairs(self, cost):
            """
            :type cost: List[int]
            :rtype: int
            """
            if len(cost) == 1:
                return cost[0]
            if len(cost) == 2:
                return min(cost)
            for i in range(2, len(cost)):
                cost[i] += min(cost[i-1], cost[i-2])
            return min(cost[-1], cost[-2])
    

    55. Jump Game

    https://leetcode.com/problems/jump-game/description/

    其实这道题使用贪心算法比较好,所以第一种我们提供一个贪心算法的解法。虽然LeetCode加入了Test Case:[25000, 24999, 24998…]之后动态规划会超时,但动态规划的思想还是很值得借鉴。所以第二种是原版模板动态规划解法,第三种是针对该题优化版的动态规划解法。优化点1:既然某点可达,那么它前面的点肯定全部可达。优化点2:如果某点不可达了,直接返回false即可,不需要再往后计算了。
    代码如下:

    class Solution:
        def canJump(self, nums):
            """
            :type nums: List[int]
            :rtype: bool
            """
            reach = 0
            for i in range(len(nums)):
                if i > reach:
                    return False
                reach = max(reach, i + nums[i])
            return True
    

    动态规划代码是之前用java写的,仅供参考。
    代码如下:

        // DP-Original-TLE
        public boolean canJump(int[] A) {
            if(A == null || A.length == 0){
                return true;
            }
            boolean[] reachable = new boolean[A.length];
            reachable[0] = true;
            for(int i = 1; i < A.length; i++){
                for(int j = 0; j < i; j++){
                    if(reachable[j] && A[j] + j >= i){
                        reachable[i] = true;
                        break;
                    }
                }
            }
            return reachable[A.length - 1];
        }
        
        // DP-Optimized-TLE
        public boolean canJump(int[] A) {
            if(A == null || A.length == 0){
                return true;
            }
            for(int i = 1; i < A.length; i++){
                boolean reachable = false;
                for(int j = 0; j < i; j++){
                    if(A[j] + j >= i){
                        reachable = true;
                        break;
                    }
                }
                if(!reachable){
                    return false;
                }
            }
            return true;
        }
    

    45. Jump Game II

    https://leetcode.com/problems/jump-game-ii/description/

    同样解法一使用贪心算法。
    代码如下:

    class Solution:
        def jump(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            step = 0
            reach = 0
            lastReach = 0
            for i in range(len(nums)):
                if i > lastReach:
                    step += 1
                    lastReach = reach
                if lastReach >= len(nums) - 1:
                    return step
                reach = max(reach, nums[i] + i)
            return -1
    

    解法二使用模板动态规划,但会超时。

    class Solution:
        def jump(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            res = [0] * len(nums)
            for i in range(1, len(nums)):
                res[i] = i
                for j in range(i):
                    if j + nums[j] >= i:
                        res[i] = min(res[i], res[j] + 1)
            return res[-1]
    

    相关文章

      网友评论

          本文标题:LeetCode #70 #746 #55 #45 2018-0

          本文链接:https://www.haomeiwen.com/subject/oririftx.html