Redisson分散式鎖之公平鎖原理 Redisson分散式鎖之非公平鎖原理
阿新 • • 發佈:2022-03-20
最小編輯代價
題目:最小編輯代價
《程式設計師程式碼面試指南》第68題 P230 難度:校★★★☆
同樣分為經典動態規劃和經典動態規劃結合空間壓縮兩種方法。
經典動態規劃方法:
同樣建立二維動態規劃表,大小為(M+1)×(N+1)的矩陣dp,dp[i][j]的值代表str1[0..i-1]編輯成str2[0..j-1]的最小代價。
dp矩陣每個位置的值計算如下:
- dp[0][0]=0
- 第一列dp[i][0]=dc*i
- 第一行dp[0][j]=ic*j
-
其它位置dp[i][j],取以下四種可能的值中的最小值:
- dc+dp[i-1][j]
- dp[i][j-1]+ic
- 如果str1[i-1]!=str2[j-1]
- 如果str1[i-1]==str2[j-1],dp[i-1][j-1]
public int minCost1(String str1, String str2, int ic, int dc, int rc) { if (str1 == null || str2 == null) { return 0; } char[] chs1 = str1.toCharArray(); char[] chs2 = str2.toCharArray(); int row = chs1.length + 1; int col = chs2.length + 1; int[][] dp = new int[row][col]; for (int i = 1; i < row; i++) { dp[i][0] = dc * i; } for (int j = 1; j < col; j++) { dp[0][j] = ic * j; } for (int i = 1; i < row; i++) { for (int j = 1; j < col; j++) { if (chs1[i - 1] == chs2[j - 1]) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = dp[i - 1][j - 1] + rc; } dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + ic); dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + dc); } } return dp[row - 1][col - 1]; }
經典動態規劃結合空間壓縮方法:
與“矩陣的最小路徑和”問題不同,本題dp[i][j]依賴dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]。還需要一個變數來儲存dp[j-1]沒更新之前的值,即dp[i-1][j-1]。
此外,選擇str1和str2中長度較短的一個作為列對應的字串,長度較長的一個作為行對應的字串。如果str1做了列對應的字串,把插入代價ic和刪除代價dc交換一下即可。
public int minCost2(String str1, String str2, int ic, int dc, int rc) { if (str1 == null || str2 == null) { return 0; } char[] chs1 = str1.toCharArray(); char[] chs2 = str2.toCharArray(); char[] longs = chs1.length >= chs2.length ? chs1 : chs2; char[] shorts = chs1.length < chs2.length ? chs1 : chs2; if (chs1.length < chs2.length) { // str2較長就交換ic和dc的值 int tmp = ic; ic = dc; dc = tmp; } int[] dp = new int[shorts.length + 1]; for (int i = 1; i <= shorts.length; i++) { dp[i] = ic * i; } for (int i = 1; i <= longs.length; i++) { int pre = dp[0]; // pre代表左上角的值ֵ dp[0] = dc * i; for (int j = 1; j <= shorts.length; j++) { int tmp = dp[j]; // dp[j]沒更新前先儲存下來 if (longs[i - 1] == shorts[j - 1]) { dp[j] = pre; } else { dp[j] = pre + rc; } dp[j] = Math.min(dp[j], dp[j - 1] + ic); dp[j] = Math.min(dp[j], tmp + dc); pre = tmp; // pre變成dp[j]沒更新前的值 } } return dp[shorts.length]; }