日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode 62, 63, 980. Unique Paths I, II, III | 62, 63, 980. 不同路径 I, II, III(暴力递归->傻缓存->动态规划)

發(fā)布時(shí)間:2024/2/28 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 62, 63, 980. Unique Paths I, II, III | 62, 63, 980. 不同路径 I, II, III(暴力递归->傻缓存->动态规划) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

62. Unique Paths

https://leetcode.com/problems/unique-paths/

注意本題只能向右 / 向上走。

DP 問題,經(jīng)典又熟悉。

暴力遞歸->傻緩存->動(dòng)態(tài)規(guī)劃。

class Solution {int M, N;public int uniquePaths(int m, int n) {M = m;N = n;// Approach 1: Recursive, Brute Force // return process1(0, 0);// Approach 2: Recursion with Memoization // int[][] dp = new int[M][N]; // dp[M - 1][N - 1] = 1; // return process2(0, 0, dp);// Approach 3: Dynamic Programmingint[][] dp = new int[M][N];for (int i = M - 1; i >= 0; i--) {dp[i][N - 1] = 1;}for (int j = N - 1; j >= 0; j--) {dp[M - 1][j] = 1;}for (int i = M - 2; i >= 0; i--) {for (int j = N - 2; j >= 0; j--) {dp[i][j] = dp[i + 1][j] + dp[i][j + 1];}}return dp[0][0];}// public int process2(int i, int j, int[][] dp) { // 從i,j到M,N共有多少種路徑 // if (i == M || j == N) return 0; // if (dp[i][j] > 0) return dp[i][j]; // dp[i][j] = process2(i + 1, j, dp) + process2(i, j + 1, dp); // return dp[i][j]; // }// public int process1(int i, int j) { // if (i == M || j == N) return 0; // if (i == M - 1 && j == N - 1) return 1; // return process1(i + 1, j) + process1(i, j + 1); // } }

63. Unique Paths II

https://leetcode.com/problems/unique-paths-ii/

DP 問題,同上題,注意本題只能向右 / 向上走,只不過多了一些障礙物。
暴力遞歸->傻緩存->動(dòng)態(tài)規(guī)劃。

class Solution {int M, N;public int uniquePathsWithObstacles(int[][] grid) {M = grid.length;N = grid[0].length;// Approach 1: Recursive, Brute Force // return process1(0, 0, grid);// Approach 2: Recursion with Memoization// int[][] dp = new int[M][N];// for (int i = 0; i < M; i++) {// Arrays.fill(dp[i], -1);// }// dp[M - 1][N - 1] = 1 - grid[M - 1][N - 1];// for (int i = M - 2; i >= 0; i--) {// if (grid[i][N - 1] == 1 || dp[i + 1][N - 1] == 0) dp[i][N - 1] = 0;// else dp[i][N - 1] = 1;// }// for (int j = N - 2; j >= 0; j--) {// if (grid[M - 1][j] == 1 || dp[M - 1][j + 1] == 0) dp[M - 1][j] = 0;// else dp[M - 1][j] = 1;// }// return process2(0, 0, grid, dp);// Approach 3: Dynamic Programmingint[][] dp = new int[M][N];dp[M - 1][N - 1] = 1 - grid[M - 1][N - 1];for (int i = M - 2; i >= 0; i--) {if (grid[i][N - 1] == 1 || dp[i + 1][N - 1] == 0) dp[i][N - 1] = 0;else dp[i][N - 1] = 1;}for (int j = N - 2; j >= 0; j--) {if (grid[M - 1][j] == 1 || dp[M - 1][j + 1] == 0) dp[M - 1][j] = 0;else dp[M - 1][j] = 1;}for (int i = M - 2; i >= 0; i--) {for (int j = N - 2; j >= 0; j--) {if (grid[i][j] == 1) dp[i][j] = 0;else dp[i][j] = dp[i + 1][j] + dp[i][j + 1];}}return dp[0][0];}// public int process2(int i, int j, int[][] grid, int[][] dp) { // 從i,j到M,N共有多少種路徑 // if (i == M || j == N || grid[i][j] == 1) return 0; // if (dp[i][j] >= 0) return dp[i][j]; // dp[i][j] = process2(i + 1, j, grid, dp) + process2(i, j + 1, grid, dp); // return dp[i][j]; // }// public int process1(int i, int j, int[][] grid) { // if (i == M || j == N || grid[i][j] == 1) return 0; // if (i == M - 1 && j == N - 1) return 1; // return process1(i + 1, j, grid) + process1(i, j + 1, grid); // } }

980. Unique Paths III

https://leetcode.com/problems/unique-paths-iii/

本題是有史以來做過的最簡(jiǎn)單的 hard 了,就是一個(gè)沒有任何優(yōu)化技巧的 backtracing,30分鐘搞定。

思路如下:因?yàn)?exactly once 語義,所以不能走重復(fù)路線,故維護(hù)一個(gè) visited 數(shù)組。另外維護(hù)一個(gè) remain 代表剩余步數(shù),當(dāng)經(jīng)過終點(diǎn)時(shí),看剩余步數(shù)是否恰好為0,或者當(dāng)剩余步數(shù)為 0 時(shí),看是否恰好經(jīng)過終點(diǎn)。否則沒有必要繼續(xù)走下去。

class Solution {int M, N;int startX, startY;int endX, endY;public int uniquePathsIII(int[][] grid) {M = grid.length;N = grid[0].length;int remain = M * N;for (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {if (grid[i][j] == -1) remain--;if (grid[i][j] == 1) {startX = i;startY = j;} else if (grid[i][j] == 2) {endX = i;endY = j;}}}boolean[][] visited = new boolean[M][N];return process(startX, startY, grid, visited, remain - 1);}// 剩余remain步,從i,j到endX, endY共有多少種路徑public int process(int i, int j, int[][] grid, boolean[][] visited, int remain) {if (i < 0 || i == M || j < 0 || j == N || visited[i][j] || grid[i][j] == -1) return 0;if (remain == 0 || i == endX && j == endY) return remain == 0 && i == endX && j == endY ? 1 : 0;visited[i][j] = true;int p1 = process(i - 1, j, grid, visited, remain - 1);int p2 = process(i + 1, j, grid, visited, remain - 1);int p3 = process(i, j - 1, grid, visited, remain - 1);int p4 = process(i, j + 1, grid, visited, remain - 1);visited[i][j] = false;return p1 + p2 + p3 + p4;} }

總結(jié)

以上是生活随笔為你收集整理的leetcode 62, 63, 980. Unique Paths I, II, III | 62, 63, 980. 不同路径 I, II, III(暴力递归->傻缓存->动态规划)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。