From 73c6e3e1785532697413bd6a150beabab7df2f05 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 9 Mar 2025 14:14:26 +0200 Subject: [PATCH 1/4] Added tasks 3477-3480 --- .../s3477_fruits_into_baskets_ii/Solution.kt | 25 ++++++++ .../s3477_fruits_into_baskets_ii/readme.md | 47 +++++++++++++++ .../Solution.kt | 34 +++++++++++ .../readme.md | 43 ++++++++++++++ .../s3479_fruits_into_baskets_iii/Solution.kt | 35 ++++++++++++ .../s3479_fruits_into_baskets_iii/readme.md | 47 +++++++++++++++ .../Solution.kt | 57 +++++++++++++++++++ .../readme.md | 41 +++++++++++++ .../SolutionTest.kt | 23 ++++++++ .../SolutionTest.kt | 24 ++++++++ .../SolutionTest.kt | 47 +++++++++++++++ .../SolutionTest.kt | 37 ++++++++++++ 12 files changed, 460 insertions(+) create mode 100644 src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt create mode 100644 src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/readme.md create mode 100644 src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.kt create mode 100644 src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/readme.md create mode 100644 src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt create mode 100644 src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/readme.md create mode 100644 src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.kt create mode 100644 src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/readme.md create mode 100644 src/test/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/SolutionTest.kt create mode 100644 src/test/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/SolutionTest.kt create mode 100644 src/test/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/SolutionTest.kt create mode 100644 src/test/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.kt 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..6f370eb6a --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt @@ -0,0 +1,25 @@ +package g3401_3500.s3477_fruits_into_baskets_ii + +// #Easy #2025_03_09_Time_6_ms_(100.00%)_Space_47.78_MB_(100.00%) + +class Solution { + fun numOfUnplacedFruits(fruits: IntArray, baskets: IntArray): Int { + val n = fruits.size + var ct = 0 + val used = BooleanArray(n) + for (fruit in fruits) { + var flag = true + for (i in 0..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..17989f1d6 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3478_choose_k_elements_with_maximum_sum/Solution.kt @@ -0,0 +1,34 @@ +package g3401_3500.s3478_choose_k_elements_with_maximum_sum + +// #Medium #2025_03_09_Time_241_ms_(100.00%)_Space_89.04_MB_(100.00%) + +import java.util.PriorityQueue + +class Solution { + fun findMaxSum(nums1: IntArray, nums2: IntArray, k: Int): LongArray { + val n = nums1.size + val arr = Array(n) { IntArray(3) } + for (i in 0.. a[0] - b[0] } + val ans = LongArray(n) + val pq = PriorityQueue() + var sum: Long = 0 + for (i in 0.. 0 && arr[i - 1][0] == arr[i][0]) { + ans[arr[i][2]] = ans[arr[i - 1][2]] + } else { + ans[arr[i][2]] = sum + } + pq.add(arr[i][1]) + sum += arr[i][1].toLong() + if (pq.size > k) { + sum -= pq.remove()!!.toLong() + } + } + return ans + } +} 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..ffd29fc5e --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt @@ -0,0 +1,35 @@ +package g3401_3500.s3479_fruits_into_baskets_iii + +// #Medium #2025_03_09_Time_605_ms_(100.00%)_Space_76.36_MB_(100.00%) + +import kotlin.math.max + +class Solution { + fun numOfUnplacedFruits(fruits: IntArray, baskets: IntArray): Int { + var unp = 0 + var max = 0 + val list: MutableList = ArrayList() + for (basket in baskets) { + list.add(basket) + max = max(max, basket) + } + for (fruit in fruits) { + if (fruit > max) { + unp++ + continue + } + var placed = false + for (j in list.indices) { + if (list[j] >= fruit) { + list.removeAt(j) + placed = true + break + } + } + if (!placed) { + unp++ + } + } + return unp + } +} 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..f6c3b40bf --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/Solution.kt @@ -0,0 +1,57 @@ +package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair + +// #Hard #2025_03_09_Time_768_ms_(100.00%)_Space_170.46_MB_(100.00%) + +import java.util.TreeMap +import kotlin.math.max + +class Solution { + fun maxSubarrays(n: Int, cp: Array): Long { + for (pair in cp) { + if (pair[0] > pair[1]) { + val temp = pair[0] + pair[0] = pair[1] + pair[1] = temp + } + } + cp.sortWith { a: IntArray, b: IntArray -> a[0].compareTo(b[0]) } + val contributions = LongArray(cp.size) + var totalPossible = n.toLong() * (n + 1) / 2 + val endPointMap = TreeMap>() + var currentIndex = cp.size - 1 + for (start in n downTo 1) { + while (currentIndex >= 0 && cp[currentIndex][0] >= start) { + val end = cp[currentIndex][1] + endPointMap.computeIfAbsent(end) { k: Int -> ArrayList() } + .add(currentIndex) + currentIndex-- + } + if (endPointMap.isEmpty()) { + continue + } + val firstEntry = endPointMap.firstEntry() + val smallestEnd: Int = firstEntry.key!! + val pairIndex: Int = firstEntry.value!![0] + if (firstEntry.value!!.size == 1) { + endPointMap.remove(smallestEnd) + } else { + firstEntry.value!!.removeAt(0) + } + val covered = n - smallestEnd + 1L + totalPossible -= covered + if (endPointMap.isEmpty()) { + contributions[pairIndex] += covered + } else { + val nextEnd: Int = endPointMap.firstKey()!! + contributions[pairIndex] += (nextEnd - smallestEnd).toLong() + } + endPointMap.computeIfAbsent(smallestEnd) { k: Int? -> ArrayList() } + .add(pairIndex) + } + var result = totalPossible + for (contribution in contributions) { + result = max(result, (totalPossible + contribution)) + } + return result + } +} 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..0bd5b0fed --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3480_maximize_subarrays_after_removing_one_conflicting_pair/SolutionTest.kt @@ -0,0 +1,37 @@ +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), + ) + } +} From ab0d85f3f213af764d95211542657f945a89a7fc Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 9 Mar 2025 15:48:02 +0200 Subject: [PATCH 2/4] Fixed sonar --- .../Solution.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index f6c3b40bf..48000ce0e 100644 --- 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 @@ -22,7 +22,7 @@ class Solution { for (start in n downTo 1) { while (currentIndex >= 0 && cp[currentIndex][0] >= start) { val end = cp[currentIndex][1] - endPointMap.computeIfAbsent(end) { k: Int -> ArrayList() } + endPointMap.computeIfAbsent(end) { _: Int -> ArrayList() } .add(currentIndex) currentIndex-- } @@ -45,7 +45,7 @@ class Solution { val nextEnd: Int = endPointMap.firstKey()!! contributions[pairIndex] += (nextEnd - smallestEnd).toLong() } - endPointMap.computeIfAbsent(smallestEnd) { k: Int? -> ArrayList() } + endPointMap.computeIfAbsent(smallestEnd) { _: Int -> ArrayList() } .add(pairIndex) } var result = totalPossible From 7f40c672df20dfd4a32cf0a1b6fe5b83678ec62b Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Mon, 10 Mar 2025 04:59:53 +0200 Subject: [PATCH 3/4] Updated tags --- .../kotlin/g3401_3500/s3477_fruits_into_baskets_ii/Solution.kt | 3 ++- .../s3478_choose_k_elements_with_maximum_sum/Solution.kt | 3 ++- .../g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt | 3 ++- .../Solution.kt | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) 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 index 6f370eb6a..269819de2 100644 --- 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 @@ -1,6 +1,7 @@ package g3401_3500.s3477_fruits_into_baskets_ii -// #Easy #2025_03_09_Time_6_ms_(100.00%)_Space_47.78_MB_(100.00%) +// #Easy #Array #Binary_Search #Simulation #Segment_Tree +// #2025_03_10_Time_4_ms_(100.00%)_Space_47.71_MB_(100.00%) class Solution { fun numOfUnplacedFruits(fruits: IntArray, baskets: IntArray): Int { 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 index 17989f1d6..7c68f9f10 100644 --- 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 @@ -1,6 +1,7 @@ package g3401_3500.s3478_choose_k_elements_with_maximum_sum -// #Medium #2025_03_09_Time_241_ms_(100.00%)_Space_89.04_MB_(100.00%) +// #Medium #Array #Sorting #Heap_Priority_Queue +// #2025_03_10_Time_238_ms_(100.00%)_Space_87.94_MB_(100.00%) import java.util.PriorityQueue 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 index ffd29fc5e..4c5da6106 100644 --- 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 @@ -1,6 +1,7 @@ package g3401_3500.s3479_fruits_into_baskets_iii -// #Medium #2025_03_09_Time_605_ms_(100.00%)_Space_76.36_MB_(100.00%) +// #Medium #Array #Binary_Search #Ordered_Set #Segment_Tree +// #2025_03_10_Time_555_ms_(100.00%)_Space_78.68_MB_(100.00%) import kotlin.math.max 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 index 48000ce0e..06da7f33c 100644 --- 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 @@ -1,6 +1,7 @@ package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair -// #Hard #2025_03_09_Time_768_ms_(100.00%)_Space_170.46_MB_(100.00%) +// #Hard #Array #Prefix_Sum #Enumeration #Segment_Tree +// #2025_03_10_Time_742_ms_(100.00%)_Space_165.07_MB_(100.00%) import java.util.TreeMap import kotlin.math.max From a36113ea04311a5ad47d396837a37ff38d5f9021 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 11 Mar 2025 03:48:33 +0200 Subject: [PATCH 4/4] Improved tasks 3477-3480 --- .../s3477_fruits_into_baskets_ii/Solution.kt | 23 ++-- .../Solution.kt | 43 ++++--- .../s3479_fruits_into_baskets_iii/Solution.kt | 57 +++++---- .../Solution.kt | 112 +++++++++++------- .../SolutionTest.kt | 8 ++ 5 files changed, 149 insertions(+), 94 deletions(-) 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 index 269819de2..2fcd12c39 100644 --- 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 @@ -1,26 +1,23 @@ package g3401_3500.s3477_fruits_into_baskets_ii // #Easy #Array #Binary_Search #Simulation #Segment_Tree -// #2025_03_10_Time_4_ms_(100.00%)_Space_47.71_MB_(100.00%) +// #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 ct = 0 - val used = BooleanArray(n) - for (fruit in fruits) { - var flag = true - for (i in 0..= currfruits) { + count++ + baskets[j] = 0 break } } - if (flag) { - ct++ - } } - return ct + return n - count } } 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 index 7c68f9f10..7580e3dcf 100644 --- 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 @@ -1,35 +1,40 @@ package g3401_3500.s3478_choose_k_elements_with_maximum_sum // #Medium #Array #Sorting #Heap_Priority_Queue -// #2025_03_10_Time_238_ms_(100.00%)_Space_87.94_MB_(100.00%) +// #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 arr = Array(n) { IntArray(3) } - for (i in 0.. a[0] - b[0] } val ans = LongArray(n) - val pq = PriorityQueue() - var sum: Long = 0 - for (i in 0.. 0 && arr[i - 1][0] == arr[i][0]) { - ans[arr[i][2]] = ans[arr[i - 1][2]] - } else { - ans[arr[i][2]] = sum + 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++ } - pq.add(arr[i][1]) - sum += arr[i][1].toLong() - if (pq.size > k) { - sum -= pq.remove()!!.toLong() + 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/s3479_fruits_into_baskets_iii/Solution.kt b/src/main/kotlin/g3401_3500/s3479_fruits_into_baskets_iii/Solution.kt index 4c5da6106..76605c96b 100644 --- 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 @@ -1,36 +1,53 @@ package g3401_3500.s3479_fruits_into_baskets_iii // #Medium #Array #Binary_Search #Ordered_Set #Segment_Tree -// #2025_03_10_Time_555_ms_(100.00%)_Space_78.68_MB_(100.00%) +// #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 { - var unp = 0 - var max = 0 - val list: MutableList = ArrayList() - for (basket in baskets) { - list.add(basket) - max = max(max, basket) + val n = baskets.size + var size = 1 + while (size < n) { + size = size shl 1 } - for (fruit in fruits) { - if (fruit > max) { - unp++ + val seg = IntArray(2 * size) + for (i in 0..= fruit) { - list.removeAt(j) - placed = true - break + var idx = 1 + while (idx < size) { + if (seg[idx shl 1] >= f) { + idx = idx shl 1 + } else { + idx = idx shl 1 or 1 } } - if (!placed) { - unp++ - } + 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 } - return unp } } 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 index 06da7f33c..4da3400a3 100644 --- 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 @@ -1,58 +1,86 @@ package g3401_3500.s3480_maximize_subarrays_after_removing_one_conflicting_pair // #Hard #Array #Prefix_Sum #Enumeration #Segment_Tree -// #2025_03_10_Time_742_ms_(100.00%)_Space_165.07_MB_(100.00%) +// #2025_03_11_Time_48_ms_(100.00%)_Space_164.15_MB_(100.00%) -import java.util.TreeMap import kotlin.math.max +import kotlin.math.min class Solution { - fun maxSubarrays(n: Int, cp: Array): Long { - for (pair in cp) { - if (pair[0] > pair[1]) { - val temp = pair[0] - pair[0] = pair[1] - pair[1] = temp + 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() } - cp.sortWith { a: IntArray, b: IntArray -> a[0].compareTo(b[0]) } - val contributions = LongArray(cp.size) - var totalPossible = n.toLong() * (n + 1) / 2 - val endPointMap = TreeMap>() - var currentIndex = cp.size - 1 - for (start in n downTo 1) { - while (currentIndex >= 0 && cp[currentIndex][0] >= start) { - val end = cp[currentIndex][1] - endPointMap.computeIfAbsent(end) { _: Int -> ArrayList() } - .add(currentIndex) - currentIndex-- + // 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() } - if (endPointMap.isEmpty()) { + } + 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 } - val firstEntry = endPointMap.firstEntry() - val smallestEnd: Int = firstEntry.key!! - val pairIndex: Int = firstEntry.value!![0] - if (firstEntry.value!!.size == 1) { - endPointMap.remove(smallestEnd) - } else { - firstEntry.value!!.removeAt(0) - } - val covered = n - smallestEnd + 1L - totalPossible -= covered - if (endPointMap.isEmpty()) { - contributions[pairIndex] += covered - } else { - val nextEnd: Int = endPointMap.firstKey()!! - contributions[pairIndex] += (nextEnd - smallestEnd).toLong() + // 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 } - endPointMap.computeIfAbsent(smallestEnd) { _: Int -> ArrayList() } - .add(pairIndex) + val newUnion = originalUnion + delta + val newValid = totalSubarrays - newUnion + best = max(best, newValid) } - var result = totalPossible - for (contribution in contributions) { - result = max(result, (totalPossible + contribution)) - } - return result + return best + } + + private fun forbiddenCount(x: Int, n: Int): Long { + return (if (x <= n) (n - x + 1) else 0).toLong() } } 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 index 0bd5b0fed..7376af066 100644 --- 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 @@ -34,4 +34,12 @@ internal class SolutionTest { equalTo(50L), ) } + + @Test + fun maxSubarrays4() { + assertThat( + Solution().maxSubarrays(25, arrayOf(intArrayOf(9, 7), intArrayOf(15, 7), intArrayOf(4, 7))), + equalTo(216L), + ) + } }