上岸演算法 I LeetCode Weekly Contest 219解題報告
阿新 • • 發佈:2020-12-15
No.1 比賽中的配對次數
解題思路
模擬過程即可,較簡單。
程式碼展示
class Solution {
public int numberOfMatches(int n) {
int res = 0;
while (n > 1) {
res += n / 2;
n = (n + 1) / 2;
}
return res;
}
}
No.2十-二進位制數的最少數目
解題思路
取決於最大的數字是多少。
程式碼展示
class Solution {
public int minPartitions(String n) { int res = 0; for (int i = 0; i < n.length(); i++) { res = Math.max(res, n.charAt(i) - '0'); } return res; }
}
No.3 石子游戲VII
解題思路
區間動態規劃問題。
定義狀態: dp[i][j] 表示區間 [i, j] 的得分差值
狀態轉移: 當一個人面臨 [i, j] 的情況時,在拿左邊和拿右邊之間選擇自己獲得分數更大的情況,詳見程式碼。
定義 prefixSum 表示字首和以輔助計算。
程式碼展示
class Solution {
public int stoneGameVII(int[] stones) { int n = stones.length; int[] prefixSum = new int[n + 1]; for (int i = 0; i < n; i++) { prefixSum[i + 1] = prefixSum[i] + stones[i]; } int[][] dp = new int[n][n]; for (int i = n - 1; i >= 0; --i) { for (int j = i; j < n; ++j) { if (i != j) { // 邊界: dp[i][i] = 0 dp[i][j] = Math.max( // 拿了左邊的 (prefixSum[j + 1] - prefixSum[i + 1]) - dp[i + 1][j], // 拿了右邊的 (prefixSum[j] - prefixSum[i]) - dp[i][j - 1] ); } } } return dp[0][n - 1]; }
}
No.4 堆疊長方體的最大高度
解題思路
該題目類似巢狀矩形的問題,而巢狀矩形問題又是最長上升子序列的變體,所以本質上和 LIS 問題沒有太大區別。
定義狀態: dp[i] 表示以 i 結尾的長方體上最高能堆疊多高。
與處理二維一樣地,先要對長方體進行排序,然後再遞推求解。
注意最終答案是 max{ dp }
程式碼展示
class Solution {
public int maxHeight(int[][] cuboids) { // 排序 for (int[] c : cuboids) { Arrays.sort(c); } Arrays.sort(cuboids, (a, b) -> { if (a[0] != b[0]) return Integer.compare(a[0], b[0]); if (a[1] != b[1]) return Integer.compare(a[1], b[1]); return Integer.compare(a[2], b[2]); }); // dp[i] 表示以第 i 個長方體為末尾時,能堆疊的最大高度 int[] dp = new int[cuboids.length]; for (int i = 0; i < cuboids.length; i++) { dp[i] = cuboids[i][2]; for (int j = 0; j < i; j++) if (cuboids[j][0] <= cuboids[i][0] && cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) { dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]); } } return Arrays.stream(dp).max().getAsInt(); }
}