No.1最大升序子数组和
解题思路
注意该题目的子数组是连续的。因此枚举起始位置即可。
代码展示
class Solution {
? ? public int maxAscendingSum(int[] nums) {
? ? ? ? int res = nums[0];
? ? ? ? for (int start = 0; start < nums.length; start++) {
? ? ? ? ? ? int sum = nums[start];
? ? ? ? ? ? for (int i = start + 1; i < nums.length; i++) {
? ? ? ? ? ? ? ? if (nums[i] > nums[i - 1]) {
? ? ? ? ? ? ? ? ? ? sum += nums[i];
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? res = Math.max(res, sum);
? ? ? ? }
? ? ? ? return res;
? ? }
}
No.2 积压订单中的订单总数
解题思路
使用?PriorityQueue?或者?TreeMap?维护两类挤压订单即可。
代码展示
class Solution {
? ? public int getNumberOfBacklogOrders(int[][] orders) {
? ? ? ? TreeMap<Integer, Integer> toSell = new TreeMap<Integer, Integer>();
? ? ? ? TreeMap<Integer, Integer> toBuy = new TreeMap<Integer, Integer>();
? ? ? ? for (var order : orders) {
? ? ? ? ? ? if (order[2] == 0) {
? ? ? ? ? ? ? ? // buy
? ? ? ? ? ? ? ? while (order[1] > 0) {
? ? ? ? ? ? ? ? ? ? var entry = toSell.firstEntry();
? ? ? ? ? ? ? ? ? ? if (entry == null || entry.getKey() > order[0]) {
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? int cnt = Math.min(entry.getValue(), order[1]);
? ? ? ? ? ? ? ? ? ? order[1] -= cnt;
? ? ? ? ? ? ? ? ? ? if (cnt == entry.getValue()) {
? ? ? ? ? ? ? ? ? ? ? ? toSell.remove(entry.getKey());
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? toSell.put(entry.getKey(), entry.getValue() - cnt);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? // break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (order[1] > 0) {
? ? ? ? ? ? ? ? ? ? toBuy.put(order[0], order[1] + toBuy.getOrDefault(order[0], 0));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? // sell
? ? ? ? ? ? ? ? while (order[1] > 0) {
? ? ? ? ? ? ? ? ? ? var entry = toBuy.lastEntry();
? ? ? ? ? ? ? ? ? ? if (entry == null || entry.getKey() < order[0]) {
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? int cnt = Math.min(entry.getValue(), order[1]);
? ? ? ? ? ? ? ? ? ? order[1] -= cnt;
? ? ? ? ? ? ? ? ? ? if (cnt == entry.getValue()) {
? ? ? ? ? ? ? ? ? ? ? ? toBuy.remove(entry.getKey());
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? toBuy.put(entry.getKey(), entry.getValue() - cnt);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? // break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (order[1] > 0) {
? ? ? ? ? ? ? ? ? ? toSell.put(order[0], order[1] + toSell.getOrDefault(order[0], 0));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? int res = 0;
? ? ? ? for (var entry : toSell.entrySet()) {
? ? ? ? ? ? res = (res + entry.getValue()) % 1000000007;
? ? ? ? }
? ? ? ? for (var entry : toBuy.entrySet()) {
? ? ? ? ? ? res = (res + entry.getValue()) % 1000000007;
? ? ? ? }
? ? ? ? return res;
? ? }
}
No.3 有界数组中指定下标处的最大值
解题思路
二分答案。当指定下标处的值确定后,贪心地令其他元素尽可能小即可,所以就是等差数列求和。
代码展示
class Solution {
? ? public int maxValue(int n, int index, int maxSum) {
? ? ? ? long l = 0, r = maxSum;
? ? ? ? while (l + 1 < r) {
? ? ? ? ? ? long mid = (l + r) / 2;
? ? ? ? ? ? if (check(mid, index, maxSum, n)) {
? ? ? ? ? ? ? ? l = mid;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? r = mid;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return (int) (check(r, index, maxSum, n) r : l);
? ? }
? ? long sum(long start, long count) {
? ? ? ? if (count <= 0) {
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ? if (start < count) {
? ? ? ? ? ? return (start + 1) * start / 2 + (count - start);
? ? ? ? }
? ? ? ? return (start + start - count + 1) * count / 2;
? ? }
? ? boolean check(long value, long index, long maxSum, long n) {
? ? ? ? long left = index;
? ? ? ? long right = n - index - 1;
? ? ? ? return sum(value - 1, left) + sum(value - 1, right) + value <= maxSum;
? ? }
}
No.4 统计异或值在范围内的数对有多少
解题思路
求?[low, high]?区间内的等同于求?[low, inf)?再减去?(high, inf)。
因此问题转换成求异或值大于给定数值的数对数量。使用字典树即可。
代码展示
class Solution {
? ? public int countPairs(int[] nums, int low, int high) {
? ? ? ? return (int) (solve(nums, low - 1) - solve(nums, high));
? ? }
? ? static class TrieTree {
? ? ? ? TrieTree[] next = new TrieTree[2];
? ? ? ? int count = 1;
? ? }
? ? long solve(int[] nums, int m) {
? ? ? ? TrieTree trieTree = buildTrieTree(nums);
? ? ? ? long result = 0;
? ? ? ? for (int i = 0; i < nums.length; i++) {
? ? ? ? ? ? result += queryTrieTree(trieTree, nums[i], m, 31);
? ? ? ? }
? ? ? ? return result / 2;
? ? }
? ? long queryTrieTree(TrieTree trieTree, int a, int m, int index) {
? ? ? ? if (trieTree == null)
? ? ? ? ? ? return 0;
? ? ? ? TrieTree current = trieTree;
? ? ? ? for (int i = index; i >= 0; i--) {
? ? ? ? ? ? int aDigit = (a >> i) & 1;
? ? ? ? ? ? int mDigit = (m >> i) & 1;
? ? ? ? ? ? if (aDigit == 1 && mDigit == 1) {
? ? ? ? ? ? ? ? if (current.next[0] == null)
? ? ? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? ? ? current = current.next[0];
? ? ? ? ? ? } else if (aDigit == 0 && mDigit == 1) {
? ? ? ? ? ? ? ? if (current.next[1] == null)
? ? ? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? ? ? current = current.next[1];
? ? ? ? ? ? } else if (aDigit == 1 && mDigit == 0) {
? ? ? ? ? ? ? ? long p = queryTrieTree(current.next[1], a, m, i - 1);
? ? ? ? ? ? ? ? long q = current.next[0] == null 0 : current.next[0].count;
? ? ? ? ? ? ? ? return p + q;
? ? ? ? ? ? } else if (aDigit == 0 && mDigit == 0) {
? ? ? ? ? ? ? ? long p = queryTrieTree(current.next[0], a, m, i - 1);
? ? ? ? ? ? ? ? long q = current.next[1] == null 0 : current.next[1].count;
? ? ? ? ? ? ? ? return p + q;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return 0;
? ? }
? ? TrieTree buildTrieTree(int[] a) {
? ? ? ? TrieTree trieTree = new TrieTree();
? ? ? ? for (int i = 0; i < a.length; i++) {
? ? ? ? ? ? TrieTree current = trieTree;
? ? ? ? ? ? for (int j = 31; j >= 0; j--) {
? ? ? ? ? ? ? ? int digit = (a[i] >> j) & 1;
? ? ? ? ? ? ? ? if (current.next[digit] == null) {
? ? ? ? ? ? ? ? ? ? current.next[digit] = new TrieTree();
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? current.next[digit].count++;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? current = current.next[digit];
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return trieTree;
? ? }
}