leetcode Day12 动规

85 阅读1分钟

396. 旋转函数

var maxRotateFunction = function(nums) {
    //依次求得旋转后的数组,然后模拟记录sum,求最大值
    let res=[]
    for(let i=0;i<nums.length;i++){
        let arr=[...nums.slice(nums.length-i),...nums.slice(0,nums.length-i)]
        res.push(getSum(arr))
    }
    return Math.max(...res)
};
const getSum=function(arr){
    let sum=0
    for(let i=0;i<arr.length;i++){
        sum+=i*arr[i]
    }
    return sum
    //超时了
}
var maxRotateFunction = function(nums) {
    //考虑每旋转一次,相当于当前sum+数组和-当前最后一位*数组长度
    let nSum=nums.reduce((a,b)=>a+b,0)
    let sum=getSum(nums)
    let res=sum
    for(let i=nums.length-1;i>=0;i--){
        //从后向前遍历数组,依次拿到旋转后数组的最后一位
        sum=sum+nSum-nums[i]*nums.length
        res=Math.max(sum,res)
    }
    return res
};
const getSum=function(arr){
    let sum=0
    for(let i=0;i<arr.length;i++){
        sum+=i*arr[i]
    }
    return sum
}

动规:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

746. 使用最小花费爬楼梯

自己写出来啦,好厉害呀嘻嘻

var minCostClimbingStairs = function(cost) {
    //dp[i]表示上到第i阶台阶的最小花费
    let dp=[]
    //dp[0]=0,dp[1]=0
    dp[0]=0,dp[1]=0
    //dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
    for(let i=2;i<=cost.length;i++){
        dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
    }
    return dp[cost.length]
};

62. 不同路径

var uniquePaths = function(m, n) {
    //dp[i][j]表示到(i,j)的路径条数
    let dp=new Array(m).fill(0).map(()=>new Array(n).fill(0))
    //所有能直线到达的路径数都为1
    for(let i=0;i<m;i++){
        dp[i][0]=1
    }
    for(let j=0;j<n;j++){
        dp[0][j]=1
    }
    //dp[i][j]=dp[i-1][j]+dp[i][j-1]
    for(let i=1;i<m;i++){
        for(let j=1;j<n;j++){
            dp[i][j]=dp[i-1][j]+dp[i][j-1]
        }
    }
    return dp[m-1][n-1]
};

63. 不同路径 II

var uniquePathsWithObstacles = function(obstacleGrid) {
    //与前一题唯一不同的就是,如果有障碍,保持dp[i][j]为0就好
    let m=obstacleGrid.length
    let n=obstacleGrid[0].length
    let dp=new Array(m).fill(0).map(()=>new Array(n).fill(0))
    for(let i=0;i<m;i++){
        if(obstacleGrid[i][0]===0){
            dp[i][0]=1
        }
        //直线上一个不可达,之后的都不可达
        else{
            break
        }
    }
    for(let i=0;i<n;i++){
        if(obstacleGrid[0][i]===0){
            dp[0][i]=1
        }
        else{
            break
        }
    }
    for(let i=1;i<m;i++){
        for(let j=1;j<n;j++){
            if(obstacleGrid[i][j]===0){
                dp[i][j]=dp[i-1][j]+dp[i][j-1]
            }
        }
    }
    return dp[m-1][n-1]
};