diff --git a/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt b/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt new file mode 100644 index 000000000..2fcd12c39 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3477_fruits_into_baskets_ii + +// #Easy #Array #Binary_Search #Simulation #Segment_Tree +// #2025_03_11_Time_3_ms_(100.00%)_Space_47.78_MB_(75.61%) + +class Solution { + fun numOfUnplacedFruits(fruits: IntArray, baskets: IntArray): Int { + val n = fruits.size + var currfruits: Int + var count = 0 + for (i in 0..= currfruits) { + count++ + baskets[j] = 0 + break + } + } + } + return n - count + } +} diff --git a/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/readme.md b/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/readme.md new file mode 100644 index 000000000..97b98f145 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.kt b/src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.kt new file mode 100644 index 000000000..7580e3dcf --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.kt @@ -0,0 +1,40 @@ +package g3401_3500.s3478_choose_k_elements_with_maximum_sum + +// #Medium #Array #Sorting #Heap_Priority_Queue +// #2025_03_11_Time_151_ms_(100.00%)_Space_93.64_MB_(40.74%) + +import java.util.PriorityQueue + +class Solution { + fun findMaxSum(nums1: IntArray, nums2: IntArray, k: Int): LongArray { + val n = nums1.size + val ans = LongArray(n) + val ps = Array(n) { i -> Point(nums1[i], nums2[i], i) } + ps.sortWith { p1: Point, p2: Point -> p1.x.compareTo(p2.x) } + val pq = PriorityQueue() + var s: Long = 0 + var i = 0 + while (i < n) { + var j = i + while (j < n && ps[j].x == ps[i].x) { + ans[ps[j].i] = s + j++ + } + for (p in i.. pq.peek()!!) { + s -= pq.poll()!!.toLong() + pq.offer(cur) + s += cur.toLong() + } + } + i = j + } + return ans + } + + private class Point(var x: Int, var y: Int, var i: Int) +} diff --git a/src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md b/src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md new file mode 100644 index 000000000..7cf567066 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt b/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt new file mode 100644 index 000000000..76605c96b --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt @@ -0,0 +1,53 @@ +package g3401_3500.s3479_fruits_into_baskets_iii + +// #Medium #Array #Binary_Search #Ordered_Set #Segment_Tree +// #2025_03_11_Time_53_ms_(92.86%)_Space_86.21_MB_(7.14%) + +import kotlin.math.max + +class Solution { + fun numOfUnplacedFruits(fruits: IntArray, baskets: IntArray): Int { + val n = baskets.size + var size = 1 + while (size < n) { + size = size shl 1 + } + val seg = IntArray(2 * size) + for (i in 0..= f) { + idx = idx shl 1 + } else { + idx = idx shl 1 or 1 + } + } + update(seg, idx - size, 0, size) + } + return ans + } + + private fun update(seg: IntArray, pos: Int, `val`: Int, size: Int) { + var i = pos + size + seg[i] = `val` + i /= 2 + while (i > 0) { + seg[i] = max(seg[i shl 1].toDouble(), seg[i shl 1 or 1].toDouble()).toInt() + i /= 2 + } + } +} diff --git a/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/readme.md b/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/readme.md new file mode 100644 index 000000000..d5f1d5942 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.kt b/src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.kt new file mode 100644 index 000000000..4da3400a3 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.kt @@ -0,0 +1,86 @@ +package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair + +// #Hard #Array #Prefix_Sum #Enumeration #Segment_Tree +// #2025_03_11_Time_48_ms_(100.00%)_Space_164.15_MB_(100.00%) + +import kotlin.math.max +import kotlin.math.min + +class Solution { + fun maxSubarrays(n: Int, conflictingPairs: Array): Long { + val totalSubarrays = n.toLong() * (n + 1) / 2 + val h = IntArray(n + 1) + val d2 = IntArray(n + 1) + h.fill(n + 1) + d2.fill(n + 1) + for (pair in conflictingPairs) { + var a = pair[0] + var b = pair[1] + if (a > b) { + val 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 + } + } + val f = IntArray(n + 2) + f[n + 1] = n + 1 + f[n] = h[n] + for (i in n - 1 downTo 1) { + f[i] = min(h[i], f[i + 1]).toInt() + } + // 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. + var originalUnion: Long = 0 + for (i in 1..n) { + if (f[i] <= n) { + originalUnion += (n - f[i] + 1).toLong() + } + } + val originalValid = totalSubarrays - originalUnion + var 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 (j in 1..n) { + // no conflicting pair at index j + if (h[j] == n + 1) { + continue + } + // Simulate removal: new candidate at j becomes d2[j] + val newCandidate = if (j < n) min(d2[j], f[j + 1]).toInt() else 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). + val newFj = newCandidate + // forbiddenCount(x) is defined as (n - x + 1) if x<= n, else 0. + var delta = forbiddenCount(newFj, n) - forbiddenCount(f[j], n) + var cur = newFj + // Now update backwards for i = j-1 down to 1. + for (i in j - 1 downTo 1) { + val newVal = 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 + } + val newUnion = originalUnion + delta + val newValid = totalSubarrays - newUnion + best = max(best, newValid) + } + return best + } + + private fun forbiddenCount(x: Int, n: Int): Long { + return (if (x <= n) (n - x + 1) else 0).toLong() + } +} diff --git a/src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md b/src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md new file mode 100644 index 000000000..eee5dacee --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.kt new file mode 100644 index 000000000..f3c454d94 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3477_fruits_into_baskets_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun numOfUnplacedFruits() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(4, 2, 5), intArrayOf(3, 5, 4)), + equalTo(1), + ) + } + + @Test + fun numOfUnplacedFruits2() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(3, 6, 1), intArrayOf(6, 4, 7)), + equalTo(0), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.kt new file mode 100644 index 000000000..6e74738bb --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.kt @@ -0,0 +1,24 @@ +package g3401_3500.s3478_choose_k_elements_with_maximum_sum + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun findMaxSum() { + assertThat( + Solution() + .findMaxSum(intArrayOf(4, 2, 1, 5, 3), intArrayOf(10, 20, 30, 40, 50), 2), + equalTo(longArrayOf(80L, 30L, 0L, 80L, 50L)), + ) + } + + @Test + fun findMaxSum2() { + assertThat( + Solution().findMaxSum(intArrayOf(2, 2, 2, 2), intArrayOf(3, 1, 2, 3), 1), + equalTo(longArrayOf(0L, 0L, 0L, 0L)), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.kt new file mode 100644 index 000000000..e3281a83f --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.kt @@ -0,0 +1,47 @@ +package g3401_3500.s3479_fruits_into_baskets_iii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun numOfUnplacedFruits() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(4, 2, 5), intArrayOf(3, 5, 4)), + equalTo(1), + ) + } + + @Test + fun numOfUnplacedFruits2() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(3, 6, 1), intArrayOf(6, 4, 7)), + equalTo(0), + ) + } + + @Test + fun numOfUnplacedFruits3() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(1, 2, 3), intArrayOf(3, 2, 1)), + equalTo(1), + ) + } + + @Test + fun numOfUnplacedFruits4() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(4, 5, 6), intArrayOf(1, 2, 3)), + equalTo(3), + ) + } + + @Test + fun numOfUnplacedFruits5() { + assertThat( + Solution().numOfUnplacedFruits(intArrayOf(1, 5, 2, 6), intArrayOf(2, 3)), + equalTo(2), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.kt new file mode 100644 index 000000000..7376af066 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.kt @@ -0,0 +1,45 @@ +package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxSubarrays() { + assertThat( + Solution().maxSubarrays( + 4, + arrayOf(intArrayOf(2, 3), intArrayOf(1, 4)), + ), + equalTo(9L), + ) + } + + @Test + fun maxSubarrays2() { + assertThat( + Solution().maxSubarrays(5, arrayOf(intArrayOf(1, 2), intArrayOf(2, 5), intArrayOf(3, 5))), + equalTo(12L), + ) + } + + @Test + fun maxSubarrays3() { + assertThat( + Solution().maxSubarrays( + 10, + arrayOf(intArrayOf(10, 5), intArrayOf(3, 8)), + ), + equalTo(50L), + ) + } + + @Test + fun maxSubarrays4() { + assertThat( + Solution().maxSubarrays(25, arrayOf(intArrayOf(9, 7), intArrayOf(15, 7), intArrayOf(4, 7))), + equalTo(216L), + ) + } +}