上岸 I LeetCode Weekly Contest 213解题报告

卖大米 2020-11-3 522


No.1能否连接形成数组

解题思路

题目所说 "数组内的元素互不相同" 是个很重要的条件.

直接从头开始看 arr, 根据当前的元素在 pieces 中找到相应的 piece 来拼接, 找不到或者拼接失败则返回 false.

代码展示

**classSolution** {     **public** boolean **canFormArray**(**int**[] arr, **int**[][] pieces){         Map<Integer, **int**[]> map = **new** HashMap<>();         **for** (**int**[] piece : pieces) {             map.put(piece[0], piece);         }         **for** (**int** i = 0; i < arr.length; ) {             **if** (!map.containsKey(arr[i])) {                 **return**false;             }             **int**[] piece = map.get(arr[i]);             **for** (**int** j = 0; j < piece.length; i++, j++) {                 **if** (arr[i] != piece[j]) {                     **return**false;                 }             }         }         **return**true;     } }

No.2 统计字典序元音字符串的数目 解题思路

可以看作动态规划, 不过比较简单.

递推公式: f(i, j) = sum(0, j)[f(i - 1, k)]

f(i, j) 表示长度为 i 的, 以元音 j 结尾的字典序字符串数目.

代码展示

class Solution {    public int countVowelStrings(int n) {         int[][] f = new int[n + 1][5];         Arrays.fill(f[1], 1);         for (int i = 2; i <=n; i++) {             for (intj = 0;j < 5; j++) {                 for (intk = 0;k <= j;k++) {                     f[i][j] += f[i-1][k];                 }             }         }         returnf[n][0] + f[n][1] + f[n][2] + f[n][3] + f[n][4];     } }

No.3可以到达的最远建筑

解题思路

二分答案.

判断是否可以到达建筑 mid, 只需要将到达该建筑前所有的 "上坡路" 排序, 坡度大的用梯子, 剩下的用砖块.

代码展示

class Solution {     publicint furthestBuilding(int[] heights, int bricks, int ladders) {         intleft = 0, right = heights.length;         while (left + 1 < right) {             intmid = (left + right) / 2;             if (check(mid, bricks, ladders, heights)) {                 left = mid;             } else {                 right = mid;             }         }         return (check(right, bricks, ladders, heights) ? right : left) - 1;     }

    boolean check(intmid, int bricks, int ladders, int[] heights) {         List diff = new ArrayList<>();         for (int i = 1; i < mid; i++) {             if (heights[i] > heights[i - 1]) {                 diff.add(heights[i] - heights[i - 1]);             }         }         Collections.sort(diff);         int sum = 0;         for (int i = 0; i <  diff.size() - ladders; i++) {             sum += diff.get(i);         }         return bricks >= sum;     } }

No.4 第K条最小指令

解题思路

先使用动态规划求出 count[i][j] 表示从 (i, j) 走到终点的方案数. 然后根据下一步的方案数判断应该往右走还是往下走.

代码展示

class Solution {     public String kthSmallestPath(int[] destination, int k) {         int row = destination[0];         int col = destination[1];         int[][] count = new int[row + 1][col + 1];         count[row][col] = 1;         dp(0, 0, count);

        StringBuilder res = new StringBuilder();         for (int x = 0, y = 0; x != row || y != col; ) {             if (x == row) {                 y++;                 res.append("H");             } else if (y == col) {                 x++;                 res.append("V");             } else if (y + 1 <=col && k <= count[x][y + 1]) {                 // 往右走的方案数不少于 k, 说明第 k 种方案在右边                 y++;                 res.append("H");             } else {                 // 往右走的方案数少于 k, 说明第 k 种方案在下边                 k-= count[x][y + 1];                 x++;                 res.append("V");             }         }         returnres.toString();     }

    privateintdp(intx, inty, int[][] count) {         if (count[x][y] > 0) {             return count[x][y];         }         if (x + 1 < count.length) {             count[x][y] += dp(x + 1, y, count);         }         if (y + 1 < count[0].length) {             count[x][y] += dp(x,y + 1, count);         }         returncount[x][y];     } }

最新回复 (0)
返回