前端算法 动态规划

800 阅读1分钟

1.爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢

function climbStairs(n) {
       let dp=[];
       dp[0]=0;
       dp[1]=1;
       dp[2]=2;
       for(let i=3;i<n;i++){
           dep[i]=dep[i-1]+dp[i-2];
       }
       return dep[n];
 }

2.打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额

function rob(nums){
    sum1=nums[0];
    sum2=nums[1];
    for(let i=2;i<nums.length;i++){
        let temp=sum1;
        sum1=sum1>sum2?sum1:sum2;
        sum2=temp+nums[i]; 
    }
    return sum1>sum2?sum1:sum2
}

3.最大正方形 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积

function maxSquare(matrix){
   let row=matrix.length;
   let column=matrix[0].length;
   let dp=new Array(row+1).fill(0).map(()=>new Array(column+1).fill(0))
   let maxLen=0;
   for(let i=1;i<row;i++){
       for(let j=1;j<column;j++{
           if(matrix[i-1][j-1]==1){
               dp[i][j]=Math.min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])+1;
               maxLen=Math.max(maxLen,dp[i][j];
           }
        }
    } 
    return maxLen*maxLen;
}

4.零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1

function coinChange(coins, amount) {
    if(amount === 0) return 0;
    //初始化长度为amount+1,值为无穷大的数组
    let dp = Array(amount+1).fill(Infinity)
    dp[0] = 0;
    for(let i = 0; i < dp.length; i++) {
        for (let j = 0; j < coins.length; j++) {
            // 如果差值小于零
            if (i - coins[j] < 0) continue;
            // 每一个金额最低需要几个硬币
            dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
        }
    }
    if(dp[amount] === Infinity) return -1;
    else return dp[amount] 
};

5.不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径

function uniquePaths(m, n) {
    const f = new Array(m).fill(0).map(() => new Array(n).fill(0));
    for (let i = 0; i < m; i++) {
        f[i][0] = 1;
    }
    for (let j = 0; j < n; j++) {
        f[0][j] = 1;
    }
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            f[i][j] = f[i - 1][j] + f[i][j - 1];
        }
    }
    return f[m - 1][n - 1];
};

6.买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

function maxProfit(prices) {
    let result = 0
    let len = prices.length
    let minPrice = Infinity

    for(let i=0; i < len; i++){
        // 当前价格比历史最低还要低,那就在这里买入
        if(prices[i] < minPrice){
            minPrice = prices[i]
        // 当前收益大于历史最大收益,那就在这里卖出
        }else if (prices[i] - minPrice > result){
            result = prices[i] - minPrice
        }
    }
    return result
};