动态规划笔记

来源:互联网 发布:自学 java c python 编辑:程序博客网 时间:2024/06/06 09:18

283. Move Zeroes
27. Remove Element
26. Remove Duplicates from Sorted Array
80. Remove Duplicates from Sorted Array II


283. Move Zeroes

// 解法一:最直观的解法,新建一个vector res,遍历nums,将非0元素依次赋值入res即可// 时间复杂度O(n),空间复杂度O(n)class Solution {public:    void moveZeroes(vector<int>& nums) {        vector<int> res(nums.size(), 0);        int index = 0;        for(auto it = nums.begin(); it != nums.end(); ++it){            if(*it != 0){                res[index] = *it;                ++index;            }                 }        nums = res;    }};



动态规划


70.Climbing Stairs


// 解法一:递归class Solution {public:    int climbStairs(int n) {        if( n == 0 || n == 1)            return 1;        return climbStairs(n-1) + climbStairs(n-2);    }};
// 解法二:递归+记忆化搜索class Solution {private:    vector<int> memo;    int calcWays(int n){        if(n == 0 || n == 1)            return 1;        if(memo[n] == -1){            memo[n] = calcWays(n-1) + calcWays(n-2);        }        return memo[n];    }public:    int climbStairs(int n) {        memo = vector<int>(n+1, -1);        return calcWays(n);    }};
// 解法三:动态规划class Solution {public:    int climbStairs(int n) {        // n >= 1        vector<int> memo(n+1, -1);        memo[0] = 1;        memo[1] = 1;        for( int i = 2 ; i <= n ; i ++ )            memo[i] = memo[i-1] + memo[i-2];        return memo[n];    }};

120. Triangle


// 自上向下class Solution {public:    int minimumTotal(vector<vector<int>>& triangle) {        vector<vector<int>> res(triangle.size(), vector<int>(triangle.size(), -1));        for(int i = 0; i < triangle.size(); ++i){            for(int j = 0; j < triangle[i].size(); ++j){                if(i == 0)                    res[i][j] = triangle[i][j];                else if(j == 0)                    res[i][j] = res[i-1][j] + triangle[i][j];                else if(j >= triangle[i-1].size())                    res[i][j] = res[i-1][j-1] + triangle[i][j];                else                    res[i][j] = min(res[i-1][j-1], res[i-1][j]) + triangle[i][j];                }            }        return *min_element(res[triangle.size()-1].begin(), res[triangle.size()-1].end());    }};

64. Minimum Path Sum


// 创建一个和输入矩阵同等大小的矩阵res// res[row][col]存储从左上角到达这个点的最小距离// res[row][col] = min(grid[row-1][col], grid[row][col-1]) + grid[row][col]class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if(grid.size() == 0)            return 0;        vector<vector<int>> res(grid.size(), vector<int>(grid[0].size(), -1));        for(int row = 0; row < grid.size(); ++row){            for(int col = 0; col < grid[0].size(); ++col){                // min(grid[row-1][col], grid[row][col-1]) + grid[row][col]                // 处于第一行,第一列                if(row == 0 && col == 0){                    res[row][col] = grid[row][col];                }                // 第一行,没有上侧元素                else if(row == 0){                    res[row][col] = res[row][col-1] + grid[row][col];                }                // 第一列,没有左侧元素                else if(col == 0){                    res[row][col] = res[row-1][col] + grid[row][col];                }                else{                    res[row][col] = min(res[row-1][col], res[row][col-1]) + grid[row][col];                }            }        }        return res[grid.size() - 1][grid[0].size() - 1];    }};

343. Integer Break


// n = 1 n = 2 n = 3比较特殊,单独考虑// n >= 4 : f(n) = max(f(n-1)*f(1), f(n-2)*f(2),...,f(1)*f(n-1))// f(n-1)f(1) 与 f(1)f(n-1)重复计算,算一半就可以了,循环条件j <= i/2即可class Solution {public:    int integerBreak(int n) {        if(n == 2)            return 1;        if(n == 3)            return 2;        // n >= 4        vector<int> res(n+1, -1);        res[1] = 1; // n = 1        res[2] = 2; // n = 2        res[3] = 3; // n = 3        for(int i = 4; i <= n; ++i){            int temp = 0;            for(int j = 1; j <= i/2; ++j){                temp = max(temp, res[j] * res[i-j]);            }            res[i] = temp;        }        return res[n];    }};

279. Perfect Squares


// 简单的动态规划思想,但leetcode超时了class Solution {public:    int numSquares(int n) {        if(n < 1)            return 0;        vector<int> res(n+1, 0);        res[0] = 0;        res[1] = 1;        for(int i = 2; i <= n; ++i){            // n本身就是一个完全平方数,不需要拆开,结果直接置为1            if(int(sqrt(i)) * int(sqrt(i)) == i)                res[i] = 1;            else{                int min_count = INT_MAX;                // 需要拆成两个数                for(int j = 1; j <= i/2; ++j){                    min_count = min(res[j]+res[i-j], min_count);                }                res[i] = min_count;            }            }        return res[n];    }};
// 改进一下:// 通过leetcodeclass Solution {public:    /* 如果一个数x可以表示为一个任意数a加上一个平方数bxb,也就是x = a + bxb,     * 那么能组成这个数x最少的平方数个数,就是能组成a最少的平方数个数加上1(因为b*b已经是平方数了)。     */    int numSquares(int n) {        // 将所有非平方数的结果置最大,保证之后比较的时候不被选中        vector<int> nums(n + 1, INT_MAX);        // 将所有整平方数的结果置1        for (int i = 0; i*i <= n; ++i)            nums[i*i] = 1;        // 从小到大找任意数a        for (int a = 0; a <= n; ++a){            // 从小到大找平方数b*b            for (int b = 0; a + b*b <= n; ++b){                // 因为a+b*b可能本身就是平方数,所以我们要取两个中较小的                nums[a + b*b] = min(nums[a] + 1, nums[a + b*b]);            }        }        return nums[n];    }};

91. Decode Ways


// 和青蛙跳台阶很像// f(n) = f(n-1) + f(n-2)// 但是多了限制条件,需要检查最后一个或两个数字是否能构成有效的编码class Solution {public:    int numDecodings(string s) {        if (s.empty())            return 0;        vector<int> res(s.size() + 1, 0);        if (s.size() >= 1 && isValidForOneBit(int(s[0] - '0')))            res[1] = 1;        if (s.size() >= 2){            if (isValidForOneBit(s[0] - '0') && isValidForOneBit(int(s[1] - '0')))                res[2] += 1;            if (isValidForTwoBit(atoi(s.substr(0, 2).c_str())))                res[2] += 1;        }        for (int i = 2; i < s.size(); ++i){            if (isValidForOneBit(int(s[i] - '0')))                res[i + 1] += res[i];            if (isValidForTwoBit(atoi(s.substr(i - 1, 2).c_str())))                res[i + 1] += res[i - 1];        }        return res[s.size()];    }    bool isValidForOneBit(int n){        return n >= 1 && n <= 9;    }    bool isValidForTwoBit(int n){        return n >= 10 && n <= 26;    }};

62. Unique Paths


// 这题动态规划就很简单了// res[row][col] += res[row-1][col] + res[row][col-1]// 注意边界条件即可class Solution {public:    int uniquePaths(int m, int n) {        if(m <= 0 || n <= 0)            return 0;        vector<vector<int>> res(m, vector<int>(n, 0));        for(int i = 0; i < n; ++i)            res[0][i] = 1;        for(int i = 0; i < m; ++i)            res[i][0] = 1;        for(int row = 1; row < m; ++row){            for(int col = 1; col < n; ++col)                res[row][col] += res[row-1][col] + res[row][col-1];        }        return res[m-1][n-1];    }};

63. Unique Paths II


// 相比上一题,多了一点点限制条件而已class Solution {public:    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {        if(obstacleGrid.size() <= 0 || obstacleGrid[0].size() <= 0)            return 0;        vector<vector<int>> res(obstacleGrid.size(), vector<int>(obstacleGrid[0].size(), 0));        if(obstacleGrid[0][0] == 1)            return 0;        res[0][0] = 1;        // 第一行        for(int col = 1; col < obstacleGrid[0].size(); ++col){            if(obstacleGrid[0][col] != 1)                res[0][col] = res[0][col-1];            else                res[0][col] = 0;        }        // 第一列        for(int row = 1; row < obstacleGrid.size(); ++row){            if(obstacleGrid[row][0] != 1)                res[row][0] = res[row-1][0];            else                res[row][0] = 0;        }        // 其他        for(int row = 1; row < obstacleGrid.size(); ++row){            for(int col = 1; col < obstacleGrid[0].size(); ++col)                if(obstacleGrid[row][col] != 1)                    res[row][col] += res[row-1][col] + res[row][col-1];                else                    res[row][col] = 0;        }        return res[obstacleGrid.size()-1][obstacleGrid[0].size()-1];    }};

198. House Robber
213. House Robber II
337. House Robber III
309. Best Time to Buy and Sell Stock with Cooldown








原创粉丝点击