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]; } }