diff --git a/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/Solution.java b/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/Solution.java new file mode 100644 index 000000000..09f39b948 --- /dev/null +++ b/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/Solution.java @@ -0,0 +1,23 @@ +package g3401_3500.s3477_fruits_into_baskets_ii; + +// #Easy #Array #Binary_Search #Simulation #Segment_Tree +// #2025_03_10_Time_1_ms_(100.00%)_Space_44.78_MB_(36.06%) + +public class Solution { + public int numOfUnplacedFruits(int[] fruits, int[] baskets) { + int n = fruits.length; + int currfruits; + int count = 0; + for (int i = 0; i < n; i++) { + currfruits = fruits[i]; + for (int j = 0; j < n; j++) { + if (baskets[j] >= currfruits) { + count++; + baskets[j] = 0; + break; + } + } + } + return n - count; + } +} diff --git a/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/readme.md b/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/readme.md new file mode 100644 index 000000000..97b98f145 --- /dev/null +++ b/src/main/java/g3401_3500/s3477_fruits_into_baskets_ii/readme.md @@ -0,0 +1,47 @@ +3477\. Fruits Into Baskets II + +Easy + +You are given two arrays of integers, `fruits` and `baskets`, each of length `n`, where `fruits[i]` represents the **quantity** of the ith type of fruit, and `baskets[j]` represents the **capacity** of the jth basket. + +From left to right, place the fruits according to these rules: + +* Each fruit type must be placed in the **leftmost available basket** with a capacity **greater than or equal** to the quantity of that fruit type. +* Each basket can hold **only one** type of fruit. +* If a fruit type **cannot be placed** in any basket, it remains **unplaced**. + +Return the number of fruit types that remain unplaced after all possible allocations are made. + +**Example 1:** + +**Input:** fruits = [4,2,5], baskets = [3,5,4] + +**Output:** 1 + +**Explanation:** + +* `fruits[0] = 4` is placed in `baskets[1] = 5`. +* `fruits[1] = 2` is placed in `baskets[0] = 3`. +* `fruits[2] = 5` cannot be placed in `baskets[2] = 4`. + +Since one fruit type remains unplaced, we return 1. + +**Example 2:** + +**Input:** fruits = [3,6,1], baskets = [6,4,7] + +**Output:** 0 + +**Explanation:** + +* `fruits[0] = 3` is placed in `baskets[0] = 6`. +* `fruits[1] = 6` cannot be placed in `baskets[1] = 4` (insufficient capacity) but can be placed in the next available basket, `baskets[2] = 7`. +* `fruits[2] = 1` is placed in `baskets[1] = 4`. + +Since all fruits are successfully placed, we return 0. + +**Constraints:** + +* `n == fruits.length == baskets.length` +* `1 <= n <= 100` +* `1 <= fruits[i], baskets[i] <= 1000` \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.java b/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.java new file mode 100644 index 000000000..f437b9d88 --- /dev/null +++ b/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.java @@ -0,0 +1,54 @@ +package g3401_3500.s3478_choose_k_elements_with_maximum_sum; + +// #Medium #Array #Sorting #Heap_Priority_Queue +// #2025_03_10_Time_105_ms_(98.60%)_Space_69.10_MB_(28.75%) + +import java.util.Arrays; +import java.util.PriorityQueue; + +public class Solution { + public long[] findMaxSum(int[] nums1, int[] nums2, int k) { + int n = nums1.length; + long[] ans = new long[n]; + Point[] ps = new Point[n]; + for (int i = 0; i < n; i++) { + ps[i] = new Point(nums1[i], nums2[i], i); + } + Arrays.sort(ps, (p1, p2) -> Integer.compare(p1.x, p2.x)); + PriorityQueue pq = new PriorityQueue<>(); + long s = 0; + int i = 0; + while (i < n) { + int j = i; + while (j < n && ps[j].x == ps[i].x) { + ans[ps[j].i] = s; + j++; + } + for (int p = i; p < j; p++) { + int cur = ps[p].y; + if (pq.size() < k) { + pq.offer(cur); + s += cur; + } else if (cur > pq.peek()) { + s -= pq.poll(); + pq.offer(cur); + s += cur; + } + } + i = j; + } + return ans; + } + + private static class Point { + int x; + int y; + int i; + + Point(int x, int y, int i) { + this.x = x; + this.y = y; + this.i = i; + } + } +} diff --git a/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md b/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md new file mode 100644 index 000000000..7cf567066 --- /dev/null +++ b/src/main/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md @@ -0,0 +1,43 @@ +3478\. Choose K Elements With Maximum Sum + +Medium + +You are given two integer arrays, `nums1` and `nums2`, both of length `n`, along with a positive integer `k`. + +For each index `i` from `0` to `n - 1`, perform the following: + +* Find **all** indices `j` where `nums1[j]` is less than `nums1[i]`. +* Choose **at most** `k` values of `nums2[j]` at these indices to **maximize** the total sum. + +Return an array `answer` of size `n`, where `answer[i]` represents the result for the corresponding index `i`. + +**Example 1:** + +**Input:** nums1 = [4,2,1,5,3], nums2 = [10,20,30,40,50], k = 2 + +**Output:** [80,30,0,80,50] + +**Explanation:** + +* For `i = 0`: Select the 2 largest values from `nums2` at indices `[1, 2, 4]` where `nums1[j] < nums1[0]`, resulting in `50 + 30 = 80`. +* For `i = 1`: Select the 2 largest values from `nums2` at index `[2]` where `nums1[j] < nums1[1]`, resulting in 30. +* For `i = 2`: No indices satisfy `nums1[j] < nums1[2]`, resulting in 0. +* For `i = 3`: Select the 2 largest values from `nums2` at indices `[0, 1, 2, 4]` where `nums1[j] < nums1[3]`, resulting in `50 + 30 = 80`. +* For `i = 4`: Select the 2 largest values from `nums2` at indices `[1, 2]` where `nums1[j] < nums1[4]`, resulting in `30 + 20 = 50`. + +**Example 2:** + +**Input:** nums1 = [2,2,2,2], nums2 = [3,1,2,3], k = 1 + +**Output:** [0,0,0,0] + +**Explanation:** + +Since all elements in `nums1` are equal, no indices satisfy the condition `nums1[j] < nums1[i]` for any `i`, resulting in 0 for all positions. + +**Constraints:** + +* `n == nums1.length == nums2.length` +* 1 <= n <= 105 +* 1 <= nums1[i], nums2[i] <= 106 +* `1 <= k <= n` \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/Solution.java b/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/Solution.java new file mode 100644 index 000000000..e18ef569c --- /dev/null +++ b/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/Solution.java @@ -0,0 +1,49 @@ +package g3401_3500.s3479_fruits_into_baskets_iii; + +// #Medium #Array #Binary_Search #Ordered_Set #Segment_Tree +// #2025_03_10_Time_38_ms_(97.76%)_Space_67.52_MB_(38.48%) + +public class Solution { + public int numOfUnplacedFruits(int[] fruits, int[] baskets) { + int n = baskets.length; + int size = 1; + while (size < n) { + size <<= 1; + } + int[] seg = new int[2 * size]; + for (int i = 0; i < n; i++) { + seg[size + i] = baskets[i]; + } + for (int i = n; i < size; i++) { + seg[size + i] = 0; + } + for (int i = size - 1; i > 0; i--) { + seg[i] = Math.max(seg[i << 1], seg[i << 1 | 1]); + } + int ans = 0; + for (int f : fruits) { + if (seg[1] < f) { + ans++; + continue; + } + int idx = 1; + while (idx < size) { + if (seg[idx << 1] >= f) { + idx = idx << 1; + } else { + idx = idx << 1 | 1; + } + } + update(seg, idx - size, 0, size); + } + return ans; + } + + private void update(int[] seg, int pos, int val, int size) { + int i = pos + size; + seg[i] = val; + for (i /= 2; i > 0; i /= 2) { + seg[i] = Math.max(seg[i << 1], seg[i << 1 | 1]); + } + } +} diff --git a/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/readme.md b/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/readme.md new file mode 100644 index 000000000..d5f1d5942 --- /dev/null +++ b/src/main/java/g3401_3500/s3479_fruits_into_baskets_iii/readme.md @@ -0,0 +1,47 @@ +3479\. Fruits Into Baskets III + +Medium + +You are given two arrays of integers, `fruits` and `baskets`, each of length `n`, where `fruits[i]` represents the **quantity** of the ith type of fruit, and `baskets[j]` represents the **capacity** of the jth basket. + +From left to right, place the fruits according to these rules: + +* Each fruit type must be placed in the **leftmost available basket** with a capacity **greater than or equal** to the quantity of that fruit type. +* Each basket can hold **only one** type of fruit. +* If a fruit type **cannot be placed** in any basket, it remains **unplaced**. + +Return the number of fruit types that remain unplaced after all possible allocations are made. + +**Example 1:** + +**Input:** fruits = [4,2,5], baskets = [3,5,4] + +**Output:** 1 + +**Explanation:** + +* `fruits[0] = 4` is placed in `baskets[1] = 5`. +* `fruits[1] = 2` is placed in `baskets[0] = 3`. +* `fruits[2] = 5` cannot be placed in `baskets[2] = 4`. + +Since one fruit type remains unplaced, we return 1. + +**Example 2:** + +**Input:** fruits = [3,6,1], baskets = [6,4,7] + +**Output:** 0 + +**Explanation:** + +* `fruits[0] = 3` is placed in `baskets[0] = 6`. +* `fruits[1] = 6` cannot be placed in `baskets[1] = 4` (insufficient capacity) but can be placed in the next available basket, `baskets[2] = 7`. +* `fruits[2] = 1` is placed in `baskets[1] = 4`. + +Since all fruits are successfully placed, we return 0. + +**Constraints:** + +* `n == fruits.length == baskets.length` +* 1 <= n <= 105 +* 1 <= fruits[i], baskets[i] <= 109 \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.java b/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.java new file mode 100644 index 000000000..03391fb5b --- /dev/null +++ b/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.java @@ -0,0 +1,85 @@ +package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair; + +// #Hard #Array #Prefix_Sum #Enumeration #Segment_Tree +// #2025_03_10_Time_20_ms_(98.86%)_Space_141.78_MB_(52.27%) + +import java.util.Arrays; + +public class Solution { + public long maxSubarrays(int n, int[][] conflictingPairs) { + long totalSubarrays = (long) n * (n + 1) / 2; + int[] h = new int[n + 1]; + int[] d2 = new int[n + 1]; + Arrays.fill(h, n + 1); + Arrays.fill(d2, n + 1); + for (int[] pair : conflictingPairs) { + int a = pair[0]; + int b = pair[1]; + if (a > b) { + int temp = a; + a = b; + b = temp; + } + if (b < h[a]) { + d2[a] = h[a]; + h[a] = b; + } else if (b < d2[a]) { + d2[a] = b; + } + } + int[] f = new int[n + 2]; + f[n + 1] = n + 1; + f[n] = h[n]; + for (int i = n - 1; i >= 1; i--) { + f[i] = Math.min(h[i], f[i + 1]); + } + // forbiddenCount(x) returns (n - x + 1) if x <= n, else 0. + // This is the number of forbidden subarrays starting at some i when f[i] = x. + long originalUnion = 0; + for (int i = 1; i <= n; i++) { + if (f[i] <= n) { + originalUnion += (n - f[i] + 1); + } + } + long originalValid = totalSubarrays - originalUnion; + long best = originalValid; + // For each index j (1 <= j <= n) where a candidate conflicting pair exists, + // simulate removal of the pair that gave h[j] (if any). + // (If there is no candidate pair at j, h[j] remains n+1.) + for (int j = 1; j <= n; j++) { + // no conflicting pair at index j + if (h[j] == n + 1) { + continue; + } + // Simulate removal: new candidate at j becomes d2[j] + int newCandidate = (j < n) ? Math.min(d2[j], f[j + 1]) : d2[j]; + // We'll recompute the new f values for indices 1..j. + // Let newF[i] denote the updated value. + // For i > j, newF[i] remains as original f[i]. + // For i = j, newF[j] = min( newCandidate, f[j+1] ) (which is newCandidate by + // definition). + int newFj = newCandidate; + // forbiddenCount(x) is defined as (n - x + 1) if x<= n, else 0. + long delta = forbiddenCount(newFj, n) - forbiddenCount(f[j], n); + int cur = newFj; + // Now update backwards for i = j-1 down to 1. + for (int i = j - 1; i >= 1; i--) { + int newVal = Math.min(h[i], cur); + // no further change for i' <= i + if (newVal == f[i]) { + break; + } + delta += forbiddenCount(newVal, n) - forbiddenCount(f[i], n); + cur = newVal; + } + long newUnion = originalUnion + delta; + long newValid = totalSubarrays - newUnion; + best = Math.max(best, newValid); + } + return best; + } + + private long forbiddenCount(int x, int n) { + return x <= n ? (n - x + 1) : 0; + } +} diff --git a/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md b/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md new file mode 100644 index 000000000..eee5dacee --- /dev/null +++ b/src/main/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md @@ -0,0 +1,41 @@ +3480\. Maximize Subarrays After Removing One Conflicting Pair + +Hard + +You are given an integer `n` which represents an array `nums` containing the numbers from 1 to `n` in order. Additionally, you are given a 2D array `conflictingPairs`, where `conflictingPairs[i] = [a, b]` indicates that `a` and `b` form a conflicting pair. + +Remove **exactly** one element from `conflictingPairs`. Afterward, count the number of non-empty subarrays of `nums` which do not contain both `a` and `b` for any remaining conflicting pair `[a, b]`. + +Return the **maximum** number of subarrays possible after removing **exactly** one conflicting pair. + +**Example 1:** + +**Input:** n = 4, conflictingPairs = [[2,3],[1,4]] + +**Output:** 9 + +**Explanation:** + +* Remove `[2, 3]` from `conflictingPairs`. Now, `conflictingPairs = [[1, 4]]`. +* There are 9 subarrays in `nums` where `[1, 4]` do not appear together. They are `[1]`, `[2]`, `[3]`, `[4]`, `[1, 2]`, `[2, 3]`, `[3, 4]`, `[1, 2, 3]` and `[2, 3, 4]`. +* The maximum number of subarrays we can achieve after removing one element from `conflictingPairs` is 9. + +**Example 2:** + +**Input:** n = 5, conflictingPairs = [[1,2],[2,5],[3,5]] + +**Output:** 12 + +**Explanation:** + +* Remove `[1, 2]` from `conflictingPairs`. Now, `conflictingPairs = [[2, 5], [3, 5]]`. +* There are 12 subarrays in `nums` where `[2, 5]` and `[3, 5]` do not appear together. +* The maximum number of subarrays we can achieve after removing one element from `conflictingPairs` is 12. + +**Constraints:** + +* 2 <= n <= 105 +* `1 <= conflictingPairs.length <= 2 * n` +* `conflictingPairs[i].length == 2` +* `1 <= conflictingPairs[i][j] <= n` +* `conflictingPairs[i][0] != conflictingPairs[i][1]` \ No newline at end of file diff --git a/src/test/java/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.java b/src/test/java/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.java new file mode 100644 index 000000000..a52f8e254 --- /dev/null +++ b/src/test/java/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.java @@ -0,0 +1,22 @@ +package g3401_3500.s3477_fruits_into_baskets_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void numOfUnplacedFruits() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {4, 2, 5}, new int[] {3, 5, 4}), + equalTo(1)); + } + + @Test + void numOfUnplacedFruits2() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {3, 6, 1}, new int[] {6, 4, 7}), + equalTo(0)); + } +} diff --git a/src/test/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.java b/src/test/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.java new file mode 100644 index 000000000..1110c6730 --- /dev/null +++ b/src/test/java/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.java @@ -0,0 +1,23 @@ +package g3401_3500.s3478_choose_k_elements_with_maximum_sum; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void findMaxSum() { + assertThat( + new Solution() + .findMaxSum(new int[] {4, 2, 1, 5, 3}, new int[] {10, 20, 30, 40, 50}, 2), + equalTo(new long[] {80L, 30L, 0L, 80L, 50L})); + } + + @Test + void findMaxSum2() { + assertThat( + new Solution().findMaxSum(new int[] {2, 2, 2, 2}, new int[] {3, 1, 2, 3}, 1), + equalTo(new long[] {0L, 0L, 0L, 0L})); + } +} diff --git a/src/test/java/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.java b/src/test/java/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.java new file mode 100644 index 000000000..869893f5e --- /dev/null +++ b/src/test/java/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.java @@ -0,0 +1,43 @@ +package g3401_3500.s3479_fruits_into_baskets_iii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void numOfUnplacedFruits() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {4, 2, 5}, new int[] {3, 5, 4}), + equalTo(1)); + } + + @Test + void numOfUnplacedFruits2() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {3, 6, 1}, new int[] {6, 4, 7}), + equalTo(0)); + } + + @Test + void numOfUnplacedFruits3() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {1, 2, 3}, new int[] {3, 2, 1}), + equalTo(1)); + } + + @Test + void numOfUnplacedFruits4() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {4, 5, 6}, new int[] {1, 2, 3}), + equalTo(3)); + } + + @Test + void numOfUnplacedFruits5() { + assertThat( + new Solution().numOfUnplacedFruits(new int[] {1, 5, 2, 6}, new int[] {2, 3}), + equalTo(2)); + } +} diff --git a/src/test/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.java b/src/test/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.java new file mode 100644 index 000000000..ef8550167 --- /dev/null +++ b/src/test/java/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.java @@ -0,0 +1,31 @@ +package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxSubarrays() { + assertThat(new Solution().maxSubarrays(4, new int[][] {{2, 3}, {1, 4}}), equalTo(9L)); + } + + @Test + void maxSubarrays2() { + assertThat( + new Solution().maxSubarrays(5, new int[][] {{1, 2}, {2, 5}, {3, 5}}), equalTo(12L)); + } + + @Test + void maxSubarrays3() { + assertThat(new Solution().maxSubarrays(10, new int[][] {{10, 5}, {3, 8}}), equalTo(50L)); + } + + @Test + void maxSubarrays4() { + assertThat( + new Solution().maxSubarrays(25, new int[][] {{9, 7}, {15, 7}, {4, 7}}), + equalTo(216L)); + } +}