No.1 卡车上的最大单元数
解题思路
优先应用容量大的箱子即可。
代码展现
class Solution { public int maximumUnits(int[][] boxTypes, int truckSize) { Arrays.sort(boxTypes, (a, b) -> (b[1] - a[1])); int res = 0; for (var box : boxTypes) { int cnt = Math.min(truckSize, box[0]); res += cnt * box[1]; truckSize -= cnt; } return res; }}
No.2 大餐计数
解题思路
枚举即可。应用一个 Map
记录每种美味度对应的菜品数量。
代码展现
class Solution { public int countPairs(int[] deliciousness) { int res = 0, mod = 1000000007, max = 2 * (1 << 20); Map<Integer, Integer> map = new HashMap<>(); for (int d : deliciousness) { for (int sum = 1; sum <= max; sum *= 2) { res = (res + map.getOrDefault(sum - d, 0)) % mod; } map.put(d, map.getOrDefault(d, 0) + 1); } return res; }}
No.3 将数组分成三个子数组的计划数
解题思路
二分查找。分成三段 left
mid
和 right
,有两个分界点,当咱们确定左侧的分界点之后,能够二分查找右侧的分界点的最大值和最小值,在此范畴内都是成立的。
代码展现
class Solution { public int waysToSplit(int[] nums) { int sum = Arrays.stream(nums).sum(); int mod = 1000000007; int cur = nums[0]; int ans = 0; int preSum[] = new int[nums.length]; preSum[0] = nums[0]; for (int i = 1; i < nums.length - 1; i++) { cur += nums[i]; preSum[i] = nums[i] + preSum[i - 1]; // 最大值 int lr = findRight(preSum, cur, i); // 最小值 int ll = findLeft(preSum, cur, sum - cur, lr); if (ll == -1 || lr == -1 || ll > lr) { continue; } ans += (lr - ll + 1); ans %= mod; } return ans; } int findRight(int[] preSum, int sum, int r) { // 右边局部的和小于等于左边 int l = 1; int ret = -1; while (l <= r) { int m = (l + r) / 2; // 0 ~ m-1 int lsum = preSum[m - 1]; // m ~ 右界 int rsum = sum - preSum[m - 1]; if (lsum <= rsum) { ret = m; l = m + 1; } else { r = m - 1; } } return ret; } int findLeft(int[] preSum, int sum, int rSum, int r) { int l = 1; int ret = -1; while (l <= r) { int m = (l + r) / 2; int midSum = sum - preSum[m - 1]; if (midSum <= rSum) { ret = m; r = m - 1; } else { l = m + 1; } } return ret; }}
No.4 失去子序列的起码操作次数
解题思路
LCS,须要应用 o(NlogN) 的算法。
代码展现
class Solution { public int minOperations(int[] target, int[] arr) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < target.length; i++) { map.put(target[i], i); } List<Integer> list = new ArrayList<>(); for (int num : arr) { if (map.containsKey(num)) { list.add(map.get(num)); } } List<Integer> list2 = new ArrayList<>(); for (int num : list) { if (list2.size() == 0 || list2.get(list2.size() - 1) < num) { list2.add(num); continue; } int l = 0, r = list2.size() - 1; while (l + 1 < r) { int mid = (l + r) / 2; if (list2.get(mid) < num) { l = mid; } else { r = mid; } } int idx = list2.get(l) >= num ? l : r; list2.set(idx, num); } return target.length - list2.size(); }}