class Solution {
public int trap(int[] height) {
if (height == null || height.length == 0) return 0;
int left = 0, right = height.length - 1;
int ans = 0;
int left_max = 0, right_max = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= left_max) {
left_max = height[left];
} else {
ans += left_max - height[left];
}
left++;
} else {
if (height[right] >= right_max) {
right_max = height[right];
} else {
ans += right_max - height[right];
}
right--;
}
}
return ans;
}
}
Google:第23题合并 K 个升序链表
import java.util.PriorityQueue;
import java.util.Comparator;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
// Edge case: if the list is null or empty
if (lists == null || lists.length == 0) return null;
// Create a priority queue (min-heap) with a custom comparator
PriorityQueue<ListNode> pq = new PriorityQueue<>(
new Comparator<ListNode>() {
public int compare(ListNode a, ListNode b) {
return a.val - b.val;
}
}
);
// Add the head of each non-empty list to the priority queue
for (ListNode node : lists) {
if (node != null) {
pq.offer(node);
}
}
// Dummy head to help build the result list
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
// While there are nodes in the priority queue
while (!pq.isEmpty()) {
// Remove the smallest node
ListNode minNode = pq.poll();
// Add it to the merged list
tail.next = minNode;
tail = tail.next;
// If there's a next node, add it to the priority queue
if (minNode.next != null) {
pq.offer(minNode.next);
}
}
// Return the merged list
return dummy.next;
}
}
腾讯:第546题移除盒子
class Solution {
public int removeBoxes(int[] boxes) {
int n = boxes.length;
int[][][] dp = new int[n][n][n];
return calculatePoints(boxes, dp, 0, n - 1, 0);
}
private int calculatePoints(int[] boxes, int[][][] dp, int l, int r, int k) {
if (l > r) return 0;
if (dp[l][r][k] != 0) return dp[l][r][k];
// Optimization: Increase count k while the next boxes are the same color as boxes[l]
int origL = l;
int origK = k;
while (l + 1 <= r && boxes[l] == boxes[l + 1]) {
l++;
k++;
}
// Option 1: Remove boxes[l] (and any contiguous boxes of the same color)
int res = (k + 1) * (k + 1) + calculatePoints(boxes, dp, l + 1, r, 0);
// Option 2: Try to merge non-contiguous boxes of the same color
for (int m = l + 1; m <= r; m++) {
if (boxes[m] == boxes[l]) {
int temp = calculatePoints(boxes, dp, l + 1, m - 1, 0)
+ calculatePoints(boxes, dp, m, r, k + 1);
if (temp > res) {
res = temp;
}
}
}
dp[origL][r][origK] = res;
return res;
}
}
阿里巴巴:第548题将数组分割成和相等的子数组
class Solution {
public boolean splitArray(int[] nums) {
int n = nums.length;
if (n < 7) return false;
// Compute prefix sums
int[] prefixSum = new int[n + 1];
for (int idx = 0; idx < n; idx++) {
prefixSum[idx + 1] = prefixSum[idx] + nums[idx];
}
// Iterate over possible j values
for (int j = 3; j <= n - 4; j++) {
HashSet<Integer> sums = new HashSet<>();
// Find possible sums on the left side
for (int i = 1; i <= j - 2; i++) {
int sum1 = prefixSum[i] - prefixSum[0]; // sum(0, i - 1)
int sum2 = prefixSum[j] - prefixSum[i + 1]; // sum(i + 1, j - 1)
if (sum1 == sum2) {
sums.add(sum1);
}
}
// Find possible sums on the right side and check for matches
for (int k = j + 2; k <= n - 2; k++) {
int sum3 = prefixSum[k] - prefixSum[j + 1]; // sum(j + 1, k - 1)
int sum4 = prefixSum[n] - prefixSum[k + 1]; // sum(k + 1, n - 1)
if (sum3 == sum4 && sums.contains(sum3)) {
return true;
}
}
}
return false;
}
}