動態規劃第六講——leetcode上的動態規劃匯總(下)

來源:互聯網
上載者:User

標籤:leetcode   動態規劃   

接下來的幾道題,都是有關路徑問題,這可以說是DP問題的一種典型應用。路徑有一個維度;也有兩個維度。


Eg10:Climbing Stairs


這道題目比較簡單,重在分析思路。


Eg11:Minimum Path Sum 
分析:略
class Solution {       public:                 int minPathSum(vector<vector<int> > &grid) {        int row, col;        row=grid.size();        if(row==0)              return -1;         col=grid[0].size();        int i,j;               for(j=1;j<col;j++)            grid[0][j]+=grid[0][j-1];                            for(i=1;i<row;i++){            grid[i][0]+=grid[i-1][0];        }                                       for(i=1;i<row;i++){            for(j=1;j<col;j++){                grid[i][j] += min(grid[i-1][j],grid[i][j-1]);             }                  }                   return grid[row-1][col-1];                        }               };  

Eg12:Unique Paths


分析:略
class Solution {    public:    int uniquePaths(int m, int n) {            if(m<1 || n<1){                return 0;             }            int a[m][n];            int i,j;                  fill(a[0], a[0]+n, 1);            for(j=1;j<m;j++)                a[j][0]=1;                                                                                                                                                 for(i=1;i<m;i++)                for(j=1;j<n;j++)                    a[i][j]=a[i-1][j] + a[i][j-1];            return a[m-1][n-1];     }};

Eg13:Unique Paths II


class Solution {public:      int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {        int m, n;        m=obstacleGrid.size();        if(m==0)            return 0;        n=obstacleGrid[0].size();        if(n==0)            return 0;                 int i,j;        for(i=0;i<m;i++)            for(j=0;j<n;j++)                if(obstacleGrid[i][j]==1)                    obstacleGrid[i][j]=-1;                 for(j=0;j<n;j++)            if(obstacleGrid[0][j]==0)                obstacleGrid[0][j]=1;            else if(obstacleGrid[0][j]==-1)                break;       for (i = 0; i < m; ++i){           if(obstacleGrid[i][0]==0)               obstacleGrid[i][0]=1;           else if(obstacleGrid[i][0]==-1)               break;       }                                                                                                                                                                                                                                        for(i=1;i<m;i++){            for(j=1;j<n;j++){                 if(obstacleGrid[i][j]!=-1)                 obstacleGrid[i][j]=obstacleGrid[i-1][j]*(obstacleGrid[i-1][j]>0? 1:0) + obstacleGrid[i][j-1]*(obstacleGrid[i][j-1]>0? 1:0);            }          }          return obstacleGrid[m-1][n-1]>=0? obstacleGrid[m-1][n-1]:0;       }       };  


Eg14:Jump Game


分析:這道題目與其說是DP,不如說是GA(貪心演算法)。是的,這裡又隱含一條我們以後要談到的規律:談心演算法實際上是DP問題的加強版,每一個GA都可以用DP求解,反之不然。

我們仍然記得,DP問題的遞推運算式類似:
dp[i][j]= max{****};如果對max內部包含的時間複雜度是O(n)或者O(i)、O(j)的大小;那麼此時如果貪心演算法能夠使用,往往需要O(1)的演算法即可。


分析二:如果使用DP,對本題而言,dp[i] ||= {dp[j]&&(j+A[j]>=i)}

但是,這樣畢竟有些浪費,比如對於{1, 2, 3, 4, 5}很明顯到i的時候,可以忽略前面部分的i-2部分的計算結果,都可以合并到i-1之中,於是就有了GA:

class Solution {             public:                          bool canJump(int A[], int n) {        if(n<2) return true;         int maxi = A[0];        int i;             for (i = 1; i < n; ++i){            if(maxi > 0){                 maxi --;                maxi = max(maxi, A[i]) ;            }                 else               return false;        }                  return true;    }                    }; 

Eg15:Jump Game II

本題和上題目類似,代碼如下:

class Solution {      public:             int jump(int A[], int n) {        if(n<2) return 0;        int maxi=A[0] , step_left =0, res=0;         for (int i = 1; i < n; ++i){            if(maxi > 0){                if(step_left > 0){                    step_left--;                }                  else{                    res++;                    step_left = maxi-1;                }                maxi --;                maxi = max(maxi, A[i]);            }               else                return -1;        }               return res;    }   };   

Eg16:Wildcard Matching 


分析,這是一個雙序列問題,典型的DP問題。但是,如果我們使用DP來求解,這道題目會逾時。我們先來看看DP的解法。

dp[i+1][j+1]:s(0, i), t(0, j)是否能夠匹配,res=dp[m][n];


遞推關係就不寫在這裡了,這是一個2個方向的遞迴問題,需要注意的是時間和空間複雜度都是O(m*n), 因為實際測試的規模m, n在10^5, 所以沒法通過。細細思考,有很多計算是不必要的;


計算dp[i+1][j+1], 僅僅需要dp[i][j+1], dp[i+1][j], dp[i][j].另外,如果是s="aaaaaaaaaa" t="aaaaaaaaaaaaaaaaaaa*"那麼,我們計算dp[10][j],如果上一行左側元素全部是0, 本行在0之前的計算都是冗餘的。也就是說,我們僅僅需要從上一行不是0的地方開始算起。例如,上面的例子,dp[1][1]=true, dp[1][2]=false之後的dp[1][j]=false 是一直成立的。這樣,這個問題就變成了一個回溯問題,見下面的代碼。所以,這類求解存在性而非最佳化的題目,使用DP往往不是最優的解法。 下面的這個解法,本質上是貪心演算法,就是讓固定長度的s匹配最長的t;如果失敗,那麼回溯到上一個*所在的位置。

class Solution {                                               public:                                                            bool isMatch(const char *s, const char *p) {                       const char *prevs=s, *prev_start=NULL;                         while(*s){                                                         if(*p=='?' || *p==*s){p++;s++;continue;}                       if(*p == '*') {prev_start=p; p++; prevs=s;continue;}                                                                                                                   if(prev_start) {p=prev_start+1; s= prevs+1;prevs++;continue;}            return false;                                              }                                                              while((*p)=='*') p++;                                          return !(*p);                                              }                                                          }; <span style="font-size:14px;">  </span>

需要注意的是,在這種模式下,"abc" 與 "a*"是匹配的。

動態規劃第六講——leetcode上的動態規劃匯總(下)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.