《慕课网玩转算法面试》笔记及习题解答9.3

来源:互联网 发布:蛇蛇大作战网络未连接 编辑:程序博客网 时间:2024/05/18 07:19

343. Integer Break

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

Note: You may assume that n is not less than 2 and not larger than 58.

思路:考虑将问题分为求解 max( i*(n-i), i* intergerBreak(n-i) )的子问题形式,就可以考虑用递归或者动态规划的方法,递归解法如下,使用了记忆化搜索的方法

class Solution {private:    vector<int> memo;    int max3(int a, int b, int c){        return max( a, max(b,c) );    }        int breakInteger(int n){        if(n == 1)        {            //memo[1] = 1;            return 1;        }        if( memo[n] != -1)//如果已经搜索过了就记录下来,避免重复递归            return memo[n];        int res = -1;        //注意这里我们memo[n]对应第n个数        for(int i = 1; i < n+1; i++)        {            res = max3(res, i * (n-i), i* breakInteger(n-i));        }        //记录下memo[n]的值        memo[n] = res;        return res;    }    public:    int integerBreak(int n) {        memo = vector<int>(n+1,-1);        return breakInteger(n);            }};



动态规划法如下

class Solution {private:    vector<int> memo;    int max3(int a, int b, int c){        return max( a, max(b,c) );    }public:    int integerBreak(int n) {        memo = vector<int>(n+1,-1);        //递归终止条件,n=1        memo[1] = 1;        for(int i = 2; i < n+1; i++)        {            //将 i分解成j和i-j            int res = -1;            for(int j = 1; j < i; j++)            {                res = max3( res, j*(i-j), j * memo[i-j] );            }            memo[i] = res;        }        return memo[n];    }};

279. Perfect Squares

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

思路:可以将原问题分解为求 f(x) = f(n - squres[i]) + f(squres[i])的子问题,其中squares[i]是第i个平方数,我们将它记录在一个数组中即可,采用递归+记忆化搜索的方式如下,验证了几个样例应该是对的,不过leetcode上超时

class Solution {private:    vector<int> squares;    vector<int> memo;    int findSquares(int n){        if(n == 1)            return 1;        if(memo[n] != -1)            return memo[n];        int res = n+1;        for(int i = 0; squares[i] <= n && i < squares.size(); i++)        {            if(squares[i] == n )                return 1;            else                res = min(res, findSquares(squares[i]) + findSquares(n - squares[i]) );        }        memo[n] = res;        return res;    }    public:    int numSquares(int n) {        memo = vector<int>(n+1, -1);        for(int i = 1; i * i <= n; i++)            squares.push_back(i * i);        return findSquares(n);    }};
动态规划法:

class Solution {private:    vector<int> squares;    vector<int> memo;    public:    int numSquares(int n) {        memo = vector<int>(n+1, -1);        for(int i = 1; i * i <= n; i++){//记录所有的完全平方数            squares.push_back(i*i);            memo[i*i] = 1;        }        for(int j = 2; j <= n; j++)        {            if( 1== memo[j])//j就是完全平方数,直接pass                continue;            // j = squares[k] + j-squares[k]            int res = n+1;            for(int k = 0; squares[k] <= j && k < squares.size(); k++)                res = min(res,memo[squares[k]] + memo[j-squares[k]]) ;//找到j的最小平方分解,分解为j = squares[k] + j - squares[j-k]                        memo[j] = res;        }        return memo[n];                }};

91. Decode Ways

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1'B' -> 2...'Z' -> 26

Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

The number of ways decoding "12" is 2.

思路:类似于Fibonacci数列,但是要注意条件限制,挺复杂的
class Solution {public:    int numDecodings(string s) {        if(s.empty() || s[0] == '0') return 0;        vector<int> memo(s.length()+1,-1);        if(s.length() < 2) return 1;        memo[0] = 1;                for(int i = 1; i < memo.size(); i++){            memo[i] = s[i-1] == '0'? 0:memo[i-1];            if(i > 1 && s[i-2] == '1' || (s[i-2] == '2' && s[i-1] < '7') )                memo[i] += memo[i-2];        }        return memo.back();    }};

62. Unique Paths

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

思路:很明显的递推关系 path[i][j] = path[i-1][j] + path[i][j-1] ( i > 0, j > 0)

class Solution {public:    int uniquePaths(int m, int n) {        vector< vector<int>> paths(m,vector<int>(n,0) );        paths[0][0] = 1;        for(int i = 0; i < m; i++){            for(int j = 0; j < n; j++)            {                if(i > 0 && j > 0)                    paths[i][j] = paths[i-1][j] + paths[i][j-1];                else if( i > 0)                    paths[i][j] = paths[i-1][j] ;                else if( j > 0)                    paths[i][j] = paths[i][j-1];            }        }        return paths[m-1][n-1];    }};

63. Unique Paths II

Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[  [0,0,0],  [0,1,0],  [0,0,0]]

The total number of unique paths is 2.

思路:和前一道题类似,阻挡的点就设置成0就行了

class Solution {public:    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {        if(obstacleGrid.empty() || obstacleGrid[0].empty()) return 0;        int nrows = obstacleGrid.size();        int ncols = obstacleGrid[0].size();        vector< vector<int> > paths( nrows,vector<int>(ncols,0));        paths[0][0] = 1;        for(int i = 0; i < nrows; i++){            for(int j = 0; j < ncols; j++)            {                if(obstacleGrid[i][j] == 1){                    paths[i][j] = 0;                    continue;                }                                    if(i > 0 && j > 0)                    paths[i][j] = paths[i-1][j] + paths[i][j-1];                else if( i > 0)                    paths[i][j] = paths[i-1][j] ;                else if( j > 0)                    paths[i][j] = paths[i][j-1];            }        }        return paths[nrows-1][ncols-1];            }};


阅读全文
0 0
原创粉丝点击