diff --git a/README.md b/README.md
index b5f2a4ac9..0aca14a4f 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,6 @@ implementation 'com.github.javadev:leetcode-in-java:1.44'
> ["For coding interview preparation, LeetCode is one of the best online resource providing a rich library of more than 300 real coding interview questions for you to practice from using one of the 7 supported languages - C, C++, Java, Python, C#, JavaScript, Ruby."](https://www.quora.com/How-effective-is-Leetcode-for-preparing-for-technical-interviews)
##
-* [Binary Search II](#binary-search-ii)
* [Dynamic Programming I](#dynamic-programming-i)
* [Programming Skills I](#programming-skills-i)
* [Programming Skills II](#programming-skills-ii)
@@ -49,148 +48,7 @@ implementation 'com.github.javadev:leetcode-in-java:1.44'
* [Algorithm I](#algorithm-i)
* [Algorithm II](#algorithm-ii)
* [Binary Search I](#binary-search-i)
-
-### Binary Search II
-
-#### Day 1
-
-| | | | | |
-|-|-|-|-|-|-
-| 0209 |[Minimum Size Subarray Sum](src/main/java/g0201_0300/s0209_minimum_size_subarray_sum/Solution.java)| Medium | Array, Binary_Search, Prefix_Sum, Sliding_Window | 1 | 99.76
-| 0611 |[Valid Triangle Number](src/main/java/g0601_0700/s0611_valid_triangle_number/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers | 10 | 100.00
-
-#### Day 2
-
-| | | | | |
-|-|-|-|-|-|-
-| 0658 |[Find K Closest Elements](src/main/java/g0601_0700/s0658_find_k_closest_elements/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers, Heap_Priority_Queue | 3 | 99.20
-| 1894 |[Find the Student that Will Replace the Chalk](src/main/java/g1801_1900/s1894_find_the_student_that_will_replace_the_chalk/Solution.java)| Medium | Array, Binary_Search, Simulation, Prefix_Sum | 2 | 76.67
-
-#### Day 3
-
-| | | | | |
-|-|-|-|-|-|-
-| 0300 |[Longest Increasing Subsequence](src/main/java/g0201_0300/s0300_longest_increasing_subsequence/Solution.java)| Medium | Top_100_Liked_Questions, Array, Dynamic_Programming, Binary_Search, Big_O_Time_O(n\*log_n)_Space_O(n) | 3 | 95.75
-| 1760 |[Minimum Limit of Balls in a Bag](src/main/java/g1701_1800/s1760_minimum_limit_of_balls_in_a_bag/Solution.java)| Medium | Array, Binary_Search | 44 | 78.49
-
-#### Day 4
-
-| | | | | |
-|-|-|-|-|-|-
-| 0875 |[Koko Eating Bananas](src/main/java/g0801_0900/s0875_koko_eating_bananas/Solution.java)| Medium | Array, Binary_Search, LeetCode_75_Binary_Search | 15 | 91.32
-| 1552 |[Magnetic Force Between Two Balls](src/main/java/g1501_1600/s1552_magnetic_force_between_two_balls/Solution.java)| Medium | Array, Sorting, Binary_Search | 39 | 99.65
-
-#### Day 5
-
-| | | | | |
-|-|-|-|-|-|-
-| 0287 |[Find the Duplicate Number](src/main/java/g0201_0300/s0287_find_the_duplicate_number/Solution.java)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Two_Pointers, Bit_Manipulation, Big_O_Time_O(n)_Space_O(n) | 2 | 97.52
-| 1283 |[Find the Smallest Divisor Given a Threshold](src/main/java/g1201_1300/s1283_find_the_smallest_divisor_given_a_threshold/Solution.java)| Medium | Array, Binary_Search | 9 | 95.49
-
-#### Day 6
-
-| | | | | |
-|-|-|-|-|-|-
-| 1898 |[Maximum Number of Removable Characters](src/main/java/g1801_1900/s1898_maximum_number_of_removable_characters/Solution.java)| Medium | Array, String, Binary_Search | 121 | 72.51
-| 1870 |[Minimum Speed to Arrive on Time](src/main/java/g1801_1900/s1870_minimum_speed_to_arrive_on_time/Solution.java)| Medium | Array, Binary_Search | 86 | 88.58
-
-#### Day 7
-
-| | | | | |
-|-|-|-|-|-|-
-| 1482 |[Minimum Number of Days to Make m Bouquets](src/main/java/g1401_1500/s1482_minimum_number_of_days_to_make_m_bouquets/Solution.java)| Medium | Array, Binary_Search | 25 | 69.18
-| 1818 |[Minimum Absolute Sum Difference](src/main/java/g1801_1900/s1818_minimum_absolute_sum_difference/Solution.java)| Medium | Array, Sorting, Binary_Search, Ordered_Set | 13 | 99.44
-
-#### Day 8
-
-| | | | | |
-|-|-|-|-|-|-
-| 0240 |[Search a 2D Matrix II](src/main/java/g0201_0300/s0240_search_a_2d_matrix_ii/Solution.java)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Matrix, Divide_and_Conquer, Big_O_Time_O(n+m)_Space_O(1) | 5 | 99.92
-| 0275 |[H-Index II](src/main/java/g0201_0300/s0275_h_index_ii/Solution.java)| Medium | Array, Binary_Search | 0 | 100.00
-
-#### Day 9
-
-| | | | | |
-|-|-|-|-|-|-
-| 1838 |[Frequency of the Most Frequent Element](src/main/java/g1801_1900/s1838_frequency_of_the_most_frequent_element/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Prefix_Sum, Sliding_Window | 11 | 100.00
-| 0540 |[Single Element in a Sorted Array](src/main/java/g0501_0600/s0540_single_element_in_a_sorted_array/Solution.java)| Medium | Array, Binary_Search | 0 | 100.00
-
-#### Day 10
-
-| | | | | |
-|-|-|-|-|-|-
-| 0222 |[Count Complete Tree Nodes](src/main/java/g0201_0300/s0222_count_complete_tree_nodes/Solution.java)| Easy | Depth_First_Search, Tree, Binary_Search, Binary_Tree | 0 | 100.00
-| 1712 |[Ways to Split Array Into Three Subarrays](src/main/java/g1701_1800/s1712_ways_to_split_array_into_three_subarrays/Solution.java)| Medium | Array, Binary_Search, Two_Pointers, Prefix_Sum | 16 | 84.24
-
-#### Day 11
-
-| | | | | |
-|-|-|-|-|-|-
-| 0826 |[Most Profit Assigning Work](src/main/java/g0801_0900/s0826_most_profit_assigning_work/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers | 21 | 83.83
-| 0436 |[Find Right Interval](src/main/java/g0401_0500/s0436_find_right_interval/Solution.java)| Medium | Array, Sorting, Binary_Search | 20 | 81.51
-
-#### Day 12
-
-| | | | | |
-|-|-|-|-|-|-
-| 0081 |[Search in Rotated Sorted Array II](src/main/java/g0001_0100/s0081_search_in_rotated_sorted_array_ii/Solution.java)| Medium | Array, Binary_Search | 1 | 82.83
-| 0162 |[Find Peak Element](src/main/java/g0101_0200/s0162_find_peak_element/Solution.java)| Medium | Top_Interview_Questions, Array, Binary_Search, LeetCode_75_Binary_Search | 0 | 100.00
-
-#### Day 13
-
-| | | | | |
-|-|-|-|-|-|-
-| 0154 |[Find Minimum in Rotated Sorted Array II](src/main/java/g0101_0200/s0154_find_minimum_in_rotated_sorted_array_ii/Solution.java)| Hard | Array, Binary_Search | 1 | 77.09
-| 0528 |[Random Pick with Weight](src/main/java/g0501_0600/s0528_random_pick_with_weight/Solution.java)| Medium | Math, Binary_Search, Prefix_Sum, Randomized | 42 | 50.90
-
-#### Day 14
-
-| | | | | |
-|-|-|-|-|-|-
-| 1508 |[Range Sum of Sorted Subarray Sums](src/main/java/g1501_1600/s1508_range_sum_of_sorted_subarray_sums/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers | 60 | 93.84
-| 1574 |[Shortest Subarray to be Removed to Make Array Sorted](src/main/java/g1501_1600/s1574_shortest_subarray_to_be_removed_to_make_array_sorted/Solution.java)| Medium | Array, Binary_Search, Two_Pointers, Stack, Monotonic_Stack | 2 | 84.97
-
-#### Day 15
-
-| | | | | |
-|-|-|-|-|-|-
-| 1292 |[Maximum Side Length of a Square with Sum Less than or Equal to Threshold](src/main/java/g1201_1300/s1292_maximum_side_length_of_a_square_with_sum_less_than_or_equal_to_threshold/Solution.java)| Medium | Array, Binary_Search, Matrix, Prefix_Sum | 23 | 32.97
-| 1498 |[Number of Subsequences That Satisfy the Given Sum Condition](src/main/java/g1401_1500/s1498_number_of_subsequences_that_satisfy_the_given_sum_condition/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers | 27 | 99.13
-
-#### Day 16
-
-| | | | | |
-|-|-|-|-|-|-
-| 0981 |[Time Based Key-Value Store](src/main/java/g0901_1000/s0981_time_based_key_value_store/TimeMap.java)| Medium | String, Hash_Table, Binary_Search, Design | 239 | 72.78
-| 1300 |[Sum of Mutated Array Closest to Target](src/main/java/g1201_1300/s1300_sum_of_mutated_array_closest_to_target/Solution.java)| Medium | Array, Sorting, Binary_Search | 7 | 33.33
-
-#### Day 17
-
-| | | | | |
-|-|-|-|-|-|-
-| 1802 |[Maximum Value at a Given Index in a Bounded Array](src/main/java/g1801_1900/s1802_maximum_value_at_a_given_index_in_a_bounded_array/Solution.java)| Medium | Greedy, Binary_Search | 2 | 58.44
-| 1901 |[Find a Peak Element II](src/main/java/g1901_2000/s1901_find_a_peak_element_ii/Solution.java)| Medium | Array, Binary_Search, Matrix, Divide_and_Conquer | 0 | 100.00
-
-#### Day 18
-
-| | | | | |
-|-|-|-|-|-|-
-| 1146 |[Snapshot Array](src/main/java/g1101_1200/s1146_snapshot_array/SnapshotArray.java)| Medium | Array, Hash_Table, Binary_Search, Design | 68 | 45.86
-| 1488 |[Avoid Flood in The City](src/main/java/g1401_1500/s1488_avoid_flood_in_the_city/Solution.java)| Medium | Array, Hash_Table, Greedy, Binary_Search, Heap_Priority_Queue | 82 | 75.08
-
-#### Day 19
-
-| | | | | |
-|-|-|-|-|-|-
-| 1562 |[Find Latest Group of Size M](src/main/java/g1501_1600/s1562_find_latest_group_of_size_m/Solution.java)| Medium | Array, Binary_Search, Simulation | 8 | 90.00
-| 1648 |[Sell Diminishing-Valued Colored Balls](src/main/java/g1601_1700/s1648_sell_diminishing_valued_colored_balls/Solution.java)| Medium | Array, Math, Sorting, Greedy, Binary_Search, Heap_Priority_Queue | 27 | 80.64
-
-#### Day 20
-
-| | | | | |
-|-|-|-|-|-|-
-| 1201 |[Ugly Number III](src/main/java/g1201_1300/s1201_ugly_number_iii/Solution.java)| Medium | Math, Binary_Search, Number_Theory | 0 | 100.00
-| 0911 |[Online Election](src/main/java/g0901_1000/s0911_online_election/TopVotedCandidate.java)| Medium | Array, Hash_Table, Binary_Search, Design | 63 | 98.81
+* [Binary Search II](#binary-search-ii)
### Dynamic Programming I
@@ -2112,6 +1970,148 @@ implementation 'com.github.javadev:leetcode-in-java:1.44'
|-|-|-|-|-|-
| 0153 |[Find Minimum in Rotated Sorted Array](src/main/java/g0101_0200/s0153_find_minimum_in_rotated_sorted_array/Solution.java)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Big_O_Time_O(log_N)_Space_O(log_N) | 0 | 100.00
+### Binary Search II
+
+#### Day 1
+
+| | | | | |
+|-|-|-|-|-|-
+| 0209 |[Minimum Size Subarray Sum](src/main/java/g0201_0300/s0209_minimum_size_subarray_sum/Solution.java)| Medium | Array, Binary_Search, Prefix_Sum, Sliding_Window | 1 | 99.76
+| 0611 |[Valid Triangle Number](src/main/java/g0601_0700/s0611_valid_triangle_number/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers | 10 | 100.00
+
+#### Day 2
+
+| | | | | |
+|-|-|-|-|-|-
+| 0658 |[Find K Closest Elements](src/main/java/g0601_0700/s0658_find_k_closest_elements/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers, Heap_Priority_Queue | 3 | 99.20
+| 1894 |[Find the Student that Will Replace the Chalk](src/main/java/g1801_1900/s1894_find_the_student_that_will_replace_the_chalk/Solution.java)| Medium | Array, Binary_Search, Simulation, Prefix_Sum | 2 | 76.67
+
+#### Day 3
+
+| | | | | |
+|-|-|-|-|-|-
+| 0300 |[Longest Increasing Subsequence](src/main/java/g0201_0300/s0300_longest_increasing_subsequence/Solution.java)| Medium | Top_100_Liked_Questions, Array, Dynamic_Programming, Binary_Search, Big_O_Time_O(n\*log_n)_Space_O(n) | 3 | 95.75
+| 1760 |[Minimum Limit of Balls in a Bag](src/main/java/g1701_1800/s1760_minimum_limit_of_balls_in_a_bag/Solution.java)| Medium | Array, Binary_Search | 44 | 78.49
+
+#### Day 4
+
+| | | | | |
+|-|-|-|-|-|-
+| 0875 |[Koko Eating Bananas](src/main/java/g0801_0900/s0875_koko_eating_bananas/Solution.java)| Medium | Array, Binary_Search, LeetCode_75_Binary_Search | 15 | 91.32
+| 1552 |[Magnetic Force Between Two Balls](src/main/java/g1501_1600/s1552_magnetic_force_between_two_balls/Solution.java)| Medium | Array, Sorting, Binary_Search | 39 | 99.65
+
+#### Day 5
+
+| | | | | |
+|-|-|-|-|-|-
+| 0287 |[Find the Duplicate Number](src/main/java/g0201_0300/s0287_find_the_duplicate_number/Solution.java)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Two_Pointers, Bit_Manipulation, Big_O_Time_O(n)_Space_O(n) | 2 | 97.52
+| 1283 |[Find the Smallest Divisor Given a Threshold](src/main/java/g1201_1300/s1283_find_the_smallest_divisor_given_a_threshold/Solution.java)| Medium | Array, Binary_Search | 9 | 95.49
+
+#### Day 6
+
+| | | | | |
+|-|-|-|-|-|-
+| 1898 |[Maximum Number of Removable Characters](src/main/java/g1801_1900/s1898_maximum_number_of_removable_characters/Solution.java)| Medium | Array, String, Binary_Search | 121 | 72.51
+| 1870 |[Minimum Speed to Arrive on Time](src/main/java/g1801_1900/s1870_minimum_speed_to_arrive_on_time/Solution.java)| Medium | Array, Binary_Search | 86 | 88.58
+
+#### Day 7
+
+| | | | | |
+|-|-|-|-|-|-
+| 1482 |[Minimum Number of Days to Make m Bouquets](src/main/java/g1401_1500/s1482_minimum_number_of_days_to_make_m_bouquets/Solution.java)| Medium | Array, Binary_Search | 25 | 69.18
+| 1818 |[Minimum Absolute Sum Difference](src/main/java/g1801_1900/s1818_minimum_absolute_sum_difference/Solution.java)| Medium | Array, Sorting, Binary_Search, Ordered_Set | 13 | 99.44
+
+#### Day 8
+
+| | | | | |
+|-|-|-|-|-|-
+| 0240 |[Search a 2D Matrix II](src/main/java/g0201_0300/s0240_search_a_2d_matrix_ii/Solution.java)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Matrix, Divide_and_Conquer, Big_O_Time_O(n+m)_Space_O(1) | 5 | 99.92
+| 0275 |[H-Index II](src/main/java/g0201_0300/s0275_h_index_ii/Solution.java)| Medium | Array, Binary_Search | 0 | 100.00
+
+#### Day 9
+
+| | | | | |
+|-|-|-|-|-|-
+| 1838 |[Frequency of the Most Frequent Element](src/main/java/g1801_1900/s1838_frequency_of_the_most_frequent_element/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Prefix_Sum, Sliding_Window | 11 | 100.00
+| 0540 |[Single Element in a Sorted Array](src/main/java/g0501_0600/s0540_single_element_in_a_sorted_array/Solution.java)| Medium | Array, Binary_Search | 0 | 100.00
+
+#### Day 10
+
+| | | | | |
+|-|-|-|-|-|-
+| 0222 |[Count Complete Tree Nodes](src/main/java/g0201_0300/s0222_count_complete_tree_nodes/Solution.java)| Easy | Depth_First_Search, Tree, Binary_Search, Binary_Tree | 0 | 100.00
+| 1712 |[Ways to Split Array Into Three Subarrays](src/main/java/g1701_1800/s1712_ways_to_split_array_into_three_subarrays/Solution.java)| Medium | Array, Binary_Search, Two_Pointers, Prefix_Sum | 16 | 84.24
+
+#### Day 11
+
+| | | | | |
+|-|-|-|-|-|-
+| 0826 |[Most Profit Assigning Work](src/main/java/g0801_0900/s0826_most_profit_assigning_work/Solution.java)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers | 21 | 83.83
+| 0436 |[Find Right Interval](src/main/java/g0401_0500/s0436_find_right_interval/Solution.java)| Medium | Array, Sorting, Binary_Search | 20 | 81.51
+
+#### Day 12
+
+| | | | | |
+|-|-|-|-|-|-
+| 0081 |[Search in Rotated Sorted Array II](src/main/java/g0001_0100/s0081_search_in_rotated_sorted_array_ii/Solution.java)| Medium | Array, Binary_Search | 1 | 82.83
+| 0162 |[Find Peak Element](src/main/java/g0101_0200/s0162_find_peak_element/Solution.java)| Medium | Top_Interview_Questions, Array, Binary_Search, LeetCode_75_Binary_Search | 0 | 100.00
+
+#### Day 13
+
+| | | | | |
+|-|-|-|-|-|-
+| 0154 |[Find Minimum in Rotated Sorted Array II](src/main/java/g0101_0200/s0154_find_minimum_in_rotated_sorted_array_ii/Solution.java)| Hard | Array, Binary_Search | 1 | 77.09
+| 0528 |[Random Pick with Weight](src/main/java/g0501_0600/s0528_random_pick_with_weight/Solution.java)| Medium | Math, Binary_Search, Prefix_Sum, Randomized | 42 | 50.90
+
+#### Day 14
+
+| | | | | |
+|-|-|-|-|-|-
+| 1508 |[Range Sum of Sorted Subarray Sums](src/main/java/g1501_1600/s1508_range_sum_of_sorted_subarray_sums/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers | 60 | 93.84
+| 1574 |[Shortest Subarray to be Removed to Make Array Sorted](src/main/java/g1501_1600/s1574_shortest_subarray_to_be_removed_to_make_array_sorted/Solution.java)| Medium | Array, Binary_Search, Two_Pointers, Stack, Monotonic_Stack | 2 | 84.97
+
+#### Day 15
+
+| | | | | |
+|-|-|-|-|-|-
+| 1292 |[Maximum Side Length of a Square with Sum Less than or Equal to Threshold](src/main/java/g1201_1300/s1292_maximum_side_length_of_a_square_with_sum_less_than_or_equal_to_threshold/Solution.java)| Medium | Array, Binary_Search, Matrix, Prefix_Sum | 23 | 32.97
+| 1498 |[Number of Subsequences That Satisfy the Given Sum Condition](src/main/java/g1401_1500/s1498_number_of_subsequences_that_satisfy_the_given_sum_condition/Solution.java)| Medium | Array, Sorting, Binary_Search, Two_Pointers | 27 | 99.13
+
+#### Day 16
+
+| | | | | |
+|-|-|-|-|-|-
+| 0981 |[Time Based Key-Value Store](src/main/java/g0901_1000/s0981_time_based_key_value_store/TimeMap.java)| Medium | String, Hash_Table, Binary_Search, Design | 239 | 72.78
+| 1300 |[Sum of Mutated Array Closest to Target](src/main/java/g1201_1300/s1300_sum_of_mutated_array_closest_to_target/Solution.java)| Medium | Array, Sorting, Binary_Search | 7 | 33.33
+
+#### Day 17
+
+| | | | | |
+|-|-|-|-|-|-
+| 1802 |[Maximum Value at a Given Index in a Bounded Array](src/main/java/g1801_1900/s1802_maximum_value_at_a_given_index_in_a_bounded_array/Solution.java)| Medium | Greedy, Binary_Search | 2 | 58.44
+| 1901 |[Find a Peak Element II](src/main/java/g1901_2000/s1901_find_a_peak_element_ii/Solution.java)| Medium | Array, Binary_Search, Matrix, Divide_and_Conquer | 0 | 100.00
+
+#### Day 18
+
+| | | | | |
+|-|-|-|-|-|-
+| 1146 |[Snapshot Array](src/main/java/g1101_1200/s1146_snapshot_array/SnapshotArray.java)| Medium | Array, Hash_Table, Binary_Search, Design | 68 | 45.86
+| 1488 |[Avoid Flood in The City](src/main/java/g1401_1500/s1488_avoid_flood_in_the_city/Solution.java)| Medium | Array, Hash_Table, Greedy, Binary_Search, Heap_Priority_Queue | 82 | 75.08
+
+#### Day 19
+
+| | | | | |
+|-|-|-|-|-|-
+| 1562 |[Find Latest Group of Size M](src/main/java/g1501_1600/s1562_find_latest_group_of_size_m/Solution.java)| Medium | Array, Binary_Search, Simulation | 8 | 90.00
+| 1648 |[Sell Diminishing-Valued Colored Balls](src/main/java/g1601_1700/s1648_sell_diminishing_valued_colored_balls/Solution.java)| Medium | Array, Math, Sorting, Greedy, Binary_Search, Heap_Priority_Queue | 27 | 80.64
+
+#### Day 20
+
+| | | | | |
+|-|-|-|-|-|-
+| 1201 |[Ugly Number III](src/main/java/g1201_1300/s1201_ugly_number_iii/Solution.java)| Medium | Math, Binary_Search, Number_Theory | 0 | 100.00
+| 0911 |[Online Election](src/main/java/g0901_1000/s0911_online_election/TopVotedCandidate.java)| Medium | Array, Hash_Table, Binary_Search, Design | 63 | 98.81
+
## Contributing
Your ideas/fixes/algorithms are more than welcome!
diff --git a/build.gradle b/build.gradle
index 73ef36512..7b32156fa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,10 +12,10 @@ repositories {
}
dependencies {
- testImplementation 'org.junit.jupiter:junit-jupiter:[5.12.2,)'
+ testImplementation 'org.junit.jupiter:junit-jupiter:[5.13.0,)'
testImplementation 'org.hamcrest:hamcrest-core:[3.0,)'
testImplementation 'org.zapodot:embedded-db-junit-jupiter:2.2.2'
- testRuntimeOnly 'org.junit.platform:junit-platform-launcher:[1.12.2,)'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher:[1.13.0,)'
}
test {
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 002b867c4..ff23a68d7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/pom-central.xml b/pom-central.xml
index 14589c8a1..0b86ce923 100644
--- a/pom-central.xml
+++ b/pom-central.xml
@@ -61,7 +61,7 @@
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
@@ -149,13 +149,13 @@
org.junit.jupiter
junit-jupiter-api
- [5.12.2,)
+ [5.13.0,)
test
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
test
diff --git a/pom-central21.xml b/pom-central21.xml
index b863008eb..1224b55b0 100644
--- a/pom-central21.xml
+++ b/pom-central21.xml
@@ -61,7 +61,7 @@
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
@@ -155,13 +155,13 @@
org.junit.jupiter
junit-jupiter-api
- [5.12.2,)
+ [5.13.0,)
test
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
test
diff --git a/pom.xml b/pom.xml
index 8567e0b15..2d8f52583 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
@@ -172,13 +172,13 @@
org.junit.jupiter
junit-jupiter-api
- [5.12.2,)
+ [5.13.0,)
test
org.junit.jupiter
junit-jupiter-engine
- [5.12.2,)
+ [5.13.0,)
test
diff --git a/src/main/java/g0101_0200/s0178_rank_scores/script.sql b/src/main/java/g0101_0200/s0178_rank_scores/script.sql
index 0e78b870b..2773cd557 100644
--- a/src/main/java/g0101_0200/s0178_rank_scores/script.sql
+++ b/src/main/java/g0101_0200/s0178_rank_scores/script.sql
@@ -7,4 +7,3 @@ FROM
Scores
ORDER BY
Rank ASC;
-
diff --git a/src/main/java/g0101_0200/s0182_duplicate_emails/script.sql b/src/main/java/g0101_0200/s0182_duplicate_emails/script.sql
index 4dda6cf45..0cbebed39 100644
--- a/src/main/java/g0101_0200/s0182_duplicate_emails/script.sql
+++ b/src/main/java/g0101_0200/s0182_duplicate_emails/script.sql
@@ -8,4 +8,3 @@ GROUP BY
Email
HAVING
COUNT(Email) > 1;
-
diff --git a/src/main/java/g3501_3600/s3558_number_of_ways_to_assign_edge_weights_i/Solution.java b/src/main/java/g3501_3600/s3558_number_of_ways_to_assign_edge_weights_i/Solution.java
index 288e502dd..f06a99310 100644
--- a/src/main/java/g3501_3600/s3558_number_of_ways_to_assign_edge_weights_i/Solution.java
+++ b/src/main/java/g3501_3600/s3558_number_of_ways_to_assign_edge_weights_i/Solution.java
@@ -1,6 +1,6 @@
package g3501_3600.s3558_number_of_ways_to_assign_edge_weights_i;
-// #Medium #Math #Tree #Depth_First_Search #2025_05_27_Time_12_ms_(100.00%)_Space_106.62_MB_(76.01%)
+// #Medium #Math #Depth_First_Search #Tree #2025_05_27_Time_12_ms_(100.00%)_Space_106.62_MB_(76.01%)
public class Solution {
private static int mod = (int) 1e9 + 7;
diff --git a/src/main/java/g3501_3600/s3559_number_of_ways_to_assign_edge_weights_ii/Solution.java b/src/main/java/g3501_3600/s3559_number_of_ways_to_assign_edge_weights_ii/Solution.java
index 77d38483c..ce739a286 100644
--- a/src/main/java/g3501_3600/s3559_number_of_ways_to_assign_edge_weights_ii/Solution.java
+++ b/src/main/java/g3501_3600/s3559_number_of_ways_to_assign_edge_weights_ii/Solution.java
@@ -1,6 +1,6 @@
package g3501_3600.s3559_number_of_ways_to_assign_edge_weights_ii;
-// #Hard #Array #Dynamic_Programming #Math #Tree #Depth_First_Search
+// #Hard #Array #Dynamic_Programming #Math #Depth_First_Search #Tree
// #2025_05_27_Time_138_ms_(64.66%)_Space_133.20_MB_(11.56%)
import java.util.ArrayList;
diff --git a/src/main/java/g3501_3600/s3562_maximum_profit_from_trading_stocks_with_discounts/Solution.java b/src/main/java/g3501_3600/s3562_maximum_profit_from_trading_stocks_with_discounts/Solution.java
index c3b416e60..5d0233e4d 100644
--- a/src/main/java/g3501_3600/s3562_maximum_profit_from_trading_stocks_with_discounts/Solution.java
+++ b/src/main/java/g3501_3600/s3562_maximum_profit_from_trading_stocks_with_discounts/Solution.java
@@ -1,6 +1,6 @@
package g3501_3600.s3562_maximum_profit_from_trading_stocks_with_discounts;
-// #Hard #Array #Dynamic_Programming #Tree #Depth_First_Search
+// #Hard #Array #Dynamic_Programming #Depth_First_Search #Tree
// #2025_05_27_Time_27_ms_(100.00%)_Space_45.29_MB_(82.12%)
import java.util.ArrayList;
diff --git a/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/Solution.java b/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/Solution.java
new file mode 100644
index 000000000..4fbfbed1b
--- /dev/null
+++ b/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/Solution.java
@@ -0,0 +1,19 @@
+package g3501_3600.s3566_partition_array_into_two_equal_product_subsets;
+
+// #Medium #Array #Bit_Manipulation #Recursion #Enumeration
+// #2025_06_03_Time_0_ms_(100.00%)_Space_42.45_MB_(36.66%)
+
+public class Solution {
+ public boolean checkEqualPartitions(int[] nums, long target) {
+ for (int num : nums) {
+ if (target % num != 0) {
+ return false;
+ }
+ }
+ long pro = 1;
+ for (long n : nums) {
+ pro *= n;
+ }
+ return pro == target * target;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/readme.md b/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/readme.md
new file mode 100644
index 000000000..74bdaf0d7
--- /dev/null
+++ b/src/main/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/readme.md
@@ -0,0 +1,34 @@
+3566\. Partition Array into Two Equal Product Subsets
+
+Medium
+
+You are given an integer array `nums` containing **distinct** positive integers and an integer `target`.
+
+Determine if you can partition `nums` into two **non-empty** **disjoint** **subsets**, with each element belonging to **exactly one** subset, such that the product of the elements in each subset is equal to `target`.
+
+Return `true` if such a partition exists and `false` otherwise.
+
+A **subset** of an array is a selection of elements of the array.
+
+**Example 1:**
+
+**Input:** nums = [3,1,6,8,4], target = 24
+
+**Output:** true
+
+**Explanation:** The subsets `[3, 8]` and `[1, 6, 4]` each have a product of 24. Hence, the output is true.
+
+**Example 2:**
+
+**Input:** nums = [2,5,3,7], target = 15
+
+**Output:** false
+
+**Explanation:** There is no way to partition `nums` into two non-empty disjoint subsets such that both subsets have a product of 15. Hence, the output is false.
+
+**Constraints:**
+
+* `3 <= nums.length <= 12`
+* 1 <= target <= 1015
+* `1 <= nums[i] <= 100`
+* All elements of `nums` are **distinct**.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/Solution.java b/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/Solution.java
new file mode 100644
index 000000000..d36439d36
--- /dev/null
+++ b/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/Solution.java
@@ -0,0 +1,37 @@
+package g3501_3600.s3567_minimum_absolute_difference_in_sliding_submatrix;
+
+// #Medium #Array #Sorting #Matrix #2025_06_03_Time_7_ms_(99.69%)_Space_45.24_MB_(99.03%)
+
+import java.util.Arrays;
+
+public class Solution {
+ public int[][] minAbsDiff(int[][] grid, int k) {
+ int rows = grid.length;
+ int cols = grid[0].length;
+ int[][] result = new int[rows - k + 1][cols - k + 1];
+ for (int x = 0; x <= rows - k; x++) {
+ for (int y = 0; y <= cols - k; y++) {
+ int size = k * k;
+ int[] elements = new int[size];
+ int idx = 0;
+ for (int i = x; i < x + k; i++) {
+ for (int j = y; j < y + k; j++) {
+ elements[idx++] = grid[i][j];
+ }
+ }
+ Arrays.sort(elements);
+ int minDiff = Integer.MAX_VALUE;
+ for (int i = 1; i < size; i++) {
+ if (elements[i] != elements[i - 1]) {
+ minDiff = Math.min(minDiff, elements[i] - elements[i - 1]);
+ if (minDiff == 1) {
+ break;
+ }
+ }
+ }
+ result[x][y] = minDiff == Integer.MAX_VALUE ? 0 : minDiff;
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/readme.md b/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/readme.md
new file mode 100644
index 000000000..31d2e1f60
--- /dev/null
+++ b/src/main/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/readme.md
@@ -0,0 +1,60 @@
+3567\. Minimum Absolute Difference in Sliding Submatrix
+
+Medium
+
+You are given an `m x n` integer matrix `grid` and an integer `k`.
+
+For every contiguous `k x k` **submatrix** of `grid`, compute the **minimum absolute** difference between any two **distinct** values within that **submatrix**.
+
+Return a 2D array `ans` of size `(m - k + 1) x (n - k + 1)`, where `ans[i][j]` is the minimum absolute difference in the submatrix whose top-left corner is `(i, j)` in `grid`.
+
+**Note**: If all elements in the submatrix have the same value, the answer will be 0.
+
+A submatrix `(x1, y1, x2, y2)` is a matrix that is formed by choosing all cells `matrix[x][y]` where `x1 <= x <= x2` and `y1 <= y <= y2`.
+
+**Example 1:**
+
+**Input:** grid = [[1,8],[3,-2]], k = 2
+
+**Output:** [[2]]
+
+**Explanation:**
+
+* There is only one possible `k x k` submatrix: `[[1, 8], [3, -2]]`.
+* Distinct values in the submatrix are `[1, 8, 3, -2]`.
+* The minimum absolute difference in the submatrix is `|1 - 3| = 2`. Thus, the answer is `[[2]]`.
+
+**Example 2:**
+
+**Input:** grid = [[3,-1]], k = 1
+
+**Output:** [[0,0]]
+
+**Explanation:**
+
+* Both `k x k` submatrix has only one distinct element.
+* Thus, the answer is `[[0, 0]]`.
+
+**Example 3:**
+
+**Input:** grid = [[1,-2,3],[2,3,5]], k = 2
+
+**Output:** [[1,2]]
+
+**Explanation:**
+
+* There are two possible `k × k` submatrix:
+ * Starting at `(0, 0)`: `[[1, -2], [2, 3]]`.
+ * Distinct values in the submatrix are `[1, -2, 2, 3]`.
+ * The minimum absolute difference in the submatrix is `|1 - 2| = 1`.
+ * Starting at `(0, 1)`: `[[-2, 3], [3, 5]]`.
+ * Distinct values in the submatrix are `[-2, 3, 5]`.
+ * The minimum absolute difference in the submatrix is `|3 - 5| = 2`.
+* Thus, the answer is `[[1, 2]]`.
+
+**Constraints:**
+
+* `1 <= m == grid.length <= 30`
+* `1 <= n == grid[i].length <= 30`
+* -105 <= grid[i][j] <= 105
+* `1 <= k <= min(m, n)`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/Solution.java b/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/Solution.java
new file mode 100644
index 000000000..2e72c83cb
--- /dev/null
+++ b/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/Solution.java
@@ -0,0 +1,100 @@
+package g3501_3600.s3568_minimum_moves_to_clean_the_classroom;
+
+// #Medium #Array #Hash_Table #Breadth_First_Search #Matrix #Bit_Manipulation
+// #2025_06_03_Time_94_ms_(99.86%)_Space_53.76_MB_(99.86%)
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Queue;
+
+@SuppressWarnings({"java:S135", "java:S6541"})
+public class Solution {
+ private static class State {
+ int x;
+ int y;
+ int energy;
+ int mask;
+ int steps;
+
+ State(int x, int y, int energy, int mask, int steps) {
+ this.x = x;
+ this.y = y;
+ this.energy = energy;
+ this.mask = mask;
+ this.steps = steps;
+ }
+ }
+
+ public int minMoves(String[] classroom, int energy) {
+ int m = classroom.length;
+ int n = classroom[0].length();
+ char[][] grid = new char[m][n];
+ for (int i = 0; i < m; i++) {
+ grid[i] = classroom[i].toCharArray();
+ }
+ int startX = -1;
+ int startY = -1;
+ List lumetarkon = new ArrayList<>();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ char c = grid[i][j];
+ if (c == 'S') {
+ startX = i;
+ startY = j;
+ } else if (c == 'L') {
+ lumetarkon.add(new int[] {i, j});
+ }
+ }
+ }
+ int totalLitter = lumetarkon.size();
+ int allMask = (1 << totalLitter) - 1;
+ int[][][] visited = new int[m][n][1 << totalLitter];
+ for (int[][] layer : visited) {
+ for (int[] row : layer) {
+ Arrays.fill(row, -1);
+ }
+ }
+ Queue queue = new ArrayDeque<>();
+ queue.offer(new State(startX, startY, energy, 0, 0));
+ visited[startX][startY][0] = energy;
+ int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
+ while (!queue.isEmpty()) {
+ State curr = queue.poll();
+ if (curr.mask == allMask) {
+ return curr.steps;
+ }
+ for (int[] dir : dirs) {
+ int nx = curr.x + dir[0];
+ int ny = curr.y + dir[1];
+ if (nx < 0 || ny < 0 || nx >= m || ny >= n || grid[nx][ny] == 'X') {
+ continue;
+ }
+ int nextEnergy = curr.energy - 1;
+ if (nextEnergy < 0) {
+ continue;
+ }
+ char cell = grid[nx][ny];
+ if (cell == 'R') {
+ nextEnergy = energy;
+ }
+ int nextMask = curr.mask;
+ if (cell == 'L') {
+ for (int i = 0; i < lumetarkon.size(); i++) {
+ int[] pos = lumetarkon.get(i);
+ if (pos[0] == nx && pos[1] == ny) {
+ nextMask |= (1 << i);
+ break;
+ }
+ }
+ }
+ if (visited[nx][ny][nextMask] < nextEnergy) {
+ visited[nx][ny][nextMask] = nextEnergy;
+ queue.offer(new State(nx, ny, nextEnergy, nextMask, curr.steps + 1));
+ }
+ }
+ }
+ return -1;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/readme.md b/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/readme.md
new file mode 100644
index 000000000..421faa12c
--- /dev/null
+++ b/src/main/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/readme.md
@@ -0,0 +1,66 @@
+3568\. Minimum Moves to Clean the Classroom
+
+Medium
+
+You are given an `m x n` grid `classroom` where a student volunteer is tasked with cleaning up litter scattered around the room. Each cell in the grid is one of the following:
+
+* `'S'`: Starting position of the student
+* `'L'`: Litter that must be collected (once collected, the cell becomes empty)
+* `'R'`: Reset area that restores the student's energy to full capacity, regardless of their current energy level (can be used multiple times)
+* `'X'`: Obstacle the student cannot pass through
+* `'.'`: Empty space
+
+You are also given an integer `energy`, representing the student's maximum energy capacity. The student starts with this energy from the starting position `'S'`.
+
+Each move to an adjacent cell (up, down, left, or right) costs 1 unit of energy. If the energy reaches 0, the student can only continue if they are on a reset area `'R'`, which resets the energy to its **maximum** capacity `energy`.
+
+Return the **minimum** number of moves required to collect all litter items, or `-1` if it's impossible.
+
+**Example 1:**
+
+**Input:** classroom = ["S.", "XL"], energy = 2
+
+**Output:** 2
+
+**Explanation:**
+
+* The student starts at cell `(0, 0)` with 2 units of energy.
+* Since cell `(1, 0)` contains an obstacle 'X', the student cannot move directly downward.
+* A valid sequence of moves to collect all litter is as follows:
+ * Move 1: From `(0, 0)` → `(0, 1)` with 1 unit of energy and 1 unit remaining.
+ * Move 2: From `(0, 1)` → `(1, 1)` to collect the litter `'L'`.
+* The student collects all the litter using 2 moves. Thus, the output is 2.
+
+**Example 2:**
+
+**Input:** classroom = ["LS", "RL"], energy = 4
+
+**Output:** 3
+
+**Explanation:**
+
+* The student starts at cell `(0, 1)` with 4 units of energy.
+* A valid sequence of moves to collect all litter is as follows:
+ * Move 1: From `(0, 1)` → `(0, 0)` to collect the first litter `'L'` with 1 unit of energy used and 3 units remaining.
+ * Move 2: From `(0, 0)` → `(1, 0)` to `'R'` to reset and restore energy back to 4.
+ * Move 3: From `(1, 0)` → `(1, 1)` to collect the second litter `'L'`.
+* The student collects all the litter using 3 moves. Thus, the output is 3.
+
+**Example 3:**
+
+**Input:** classroom = ["L.S", "RXL"], energy = 3
+
+**Output:** \-1
+
+**Explanation:**
+
+No valid path collects all `'L'`.
+
+**Constraints:**
+
+* `1 <= m == classroom.length <= 20`
+* `1 <= n == classroom[i].length <= 20`
+* `classroom[i][j]` is one of `'S'`, `'L'`, `'R'`, `'X'`, or `'.'`
+* `1 <= energy <= 50`
+* There is exactly **one** `'S'` in the grid.
+* There are **at most** 10 `'L'` cells in the grid.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/Solution.java b/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/Solution.java
new file mode 100644
index 000000000..71d10c6e2
--- /dev/null
+++ b/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/Solution.java
@@ -0,0 +1,157 @@
+package g3501_3600.s3569_maximize_count_of_distinct_primes_after_split;
+
+// #Hard #Array #Math #Segment_Tree #Number_Theory
+// #2025_06_03_Time_280_ms_(97.30%)_Space_76.62_MB_(52.25%)
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeSet;
+
+@SuppressWarnings("java:S6541")
+public class Solution {
+ private static final int MAX_VAL = 100005;
+ private static boolean[] isPrime = new boolean[MAX_VAL];
+
+ static {
+ Arrays.fill(isPrime, true);
+ isPrime[0] = isPrime[1] = false;
+ for (int i = 2; i * i < MAX_VAL; i++) {
+ if (isPrime[i]) {
+ for (int j = i * i; j < MAX_VAL; j += i) {
+ isPrime[j] = false;
+ }
+ }
+ }
+ }
+
+ private static class Node {
+ int maxVal;
+ int lazyDelta;
+ }
+
+ private static class SegmentTree {
+ Node[] tree;
+ int n;
+
+ public SegmentTree(int n) {
+ this.n = n;
+ tree = new Node[4 * this.n];
+ for (int i = 0; i < 4 * this.n; i++) {
+ tree[i] = new Node();
+ }
+ }
+
+ private void push(int nodeIdx) {
+ if (tree[nodeIdx].lazyDelta != 0) {
+ tree[2 * nodeIdx].maxVal += tree[nodeIdx].lazyDelta;
+ tree[2 * nodeIdx].lazyDelta += tree[nodeIdx].lazyDelta;
+ tree[2 * nodeIdx + 1].maxVal += tree[nodeIdx].lazyDelta;
+ tree[2 * nodeIdx + 1].lazyDelta += tree[nodeIdx].lazyDelta;
+ tree[nodeIdx].lazyDelta = 0;
+ }
+ }
+
+ private void update(int queryStart, int queryEnd, int delta) {
+ queryStart = Math.max(1, queryStart);
+ queryEnd = Math.min(n - 1, queryEnd);
+ if (queryStart > queryEnd) {
+ return;
+ }
+ update(1, 1, n - 1, queryStart, queryEnd, delta);
+ }
+
+ private void update(
+ int nodeIdx, int start, int end, int queryStart, int queryEnd, int delta) {
+ if (start > end || start > queryEnd || end < queryStart) {
+ return;
+ }
+ if (queryStart <= start && end <= queryEnd) {
+ tree[nodeIdx].maxVal += delta;
+ tree[nodeIdx].lazyDelta += delta;
+ return;
+ }
+ push(nodeIdx);
+
+ int mid = (start + end) / 2;
+ update(2 * nodeIdx, start, mid, queryStart, queryEnd, delta);
+ update(2 * nodeIdx + 1, mid + 1, end, queryStart, queryEnd, delta);
+ tree[nodeIdx].maxVal = Math.max(tree[2 * nodeIdx].maxVal, tree[2 * nodeIdx + 1].maxVal);
+ }
+
+ public int queryMax() {
+ if (n - 1 < 1) {
+ return 0;
+ }
+ return tree[1].maxVal;
+ }
+ }
+
+ public int[] maximumCount(int[] nums, int[][] queries) {
+ int n = nums.length;
+ Map> primeIndices = new HashMap<>();
+ for (int i = 0; i < n; i++) {
+ if (isPrime[nums[i]]) {
+ primeIndices.computeIfAbsent(nums[i], k -> new TreeSet<>()).add(i);
+ }
+ }
+ SegmentTree segmentTree = new SegmentTree(n);
+ for (Map.Entry> entry : primeIndices.entrySet()) {
+ TreeSet indices = entry.getValue();
+ int first = indices.first();
+ int last = indices.last();
+ segmentTree.update(first + 1, last, 1);
+ }
+ int[] result = new int[queries.length];
+ for (int q = 0; q < queries.length; q++) {
+ int idx = queries[q][0];
+ int val = queries[q][1];
+ int oldVal = nums[idx];
+ if (isPrime[oldVal]) {
+ TreeSet indices = primeIndices.get(oldVal);
+ int oldFirst = indices.first();
+ int oldLast = indices.last();
+ indices.remove(idx);
+ if (indices.isEmpty()) {
+ primeIndices.remove(oldVal);
+ segmentTree.update(oldFirst + 1, oldLast, -1);
+ } else {
+ int newFirst = indices.first();
+ int newLast = indices.last();
+
+ if (idx == oldFirst && newFirst != oldFirst) {
+ segmentTree.update(oldFirst + 1, newFirst, -1);
+ }
+ if (idx == oldLast && newLast != oldLast) {
+ segmentTree.update(newLast + 1, oldLast, -1);
+ }
+ }
+ }
+ nums[idx] = val;
+ if (isPrime[val]) {
+ boolean wasNewPrime = !primeIndices.containsKey(val);
+ TreeSet indices = primeIndices.computeIfAbsent(val, k -> new TreeSet<>());
+ int oldFirst = indices.isEmpty() ? -1 : indices.first();
+ int oldLast = indices.isEmpty() ? -1 : indices.last();
+ indices.add(idx);
+ int newFirst = indices.first();
+ int newLast = indices.last();
+ if (wasNewPrime) {
+ segmentTree.update(newFirst + 1, newLast, 1);
+ } else {
+ if (idx < oldFirst) {
+ segmentTree.update(newFirst + 1, oldFirst, 1);
+ }
+ if (idx > oldLast) {
+ segmentTree.update(oldLast + 1, newLast, 1);
+ }
+ }
+ }
+ int totalDistinctPrimesInCurrentNums = primeIndices.size();
+ int maxIntersection = segmentTree.queryMax();
+ maxIntersection = Math.max(0, maxIntersection);
+ result[q] = totalDistinctPrimesInCurrentNums + maxIntersection;
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/readme.md b/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/readme.md
new file mode 100644
index 000000000..042623001
--- /dev/null
+++ b/src/main/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/readme.md
@@ -0,0 +1,47 @@
+3569\. Maximize Count of Distinct Primes After Split
+
+Hard
+
+You are given an integer array `nums` having length `n` and a 2D integer array `queries` where `queries[i] = [idx, val]`.
+
+For each query:
+
+1. Update `nums[idx] = val`.
+2. Choose an integer `k` with `1 <= k < n` to split the array into the non-empty prefix `nums[0..k-1]` and suffix `nums[k..n-1]` such that the sum of the counts of **distinct** prime values in each part is **maximum**.
+
+**Note:** The changes made to the array in one query persist into the next query.
+
+Return an array containing the result for each query, in the order they are given.
+
+**Example 1:**
+
+**Input:** nums = [2,1,3,1,2], queries = [[1,2],[3,3]]
+
+**Output:** [3,4]
+
+**Explanation:**
+
+* Initially `nums = [2, 1, 3, 1, 2]`.
+* After 1st query, `nums = [2, 2, 3, 1, 2]`. Split `nums` into `[2]` and `[2, 3, 1, 2]`. `[2]` consists of 1 distinct prime and `[2, 3, 1, 2]` consists of 2 distinct primes. Hence, the answer for this query is `1 + 2 = 3`.
+* After 2nd query, `nums = [2, 2, 3, 3, 2]`. Split `nums` into `[2, 2, 3]` and `[3, 2]` with an answer of `2 + 2 = 4`.
+* The output is `[3, 4]`.
+
+**Example 2:**
+
+**Input:** nums = [2,1,4], queries = [[0,1]]
+
+**Output:** [0]
+
+**Explanation:**
+
+* Initially `nums = [2, 1, 4]`.
+* After 1st query, `nums = [1, 1, 4]`. There are no prime numbers in `nums`, hence the answer for this query is 0.
+* The output is `[0]`.
+
+**Constraints:**
+
+* 2 <= n == nums.length <= 5 * 104
+* 1 <= queries.length <= 5 * 104
+* 1 <= nums[i] <= 105
+* `0 <= queries[i][0] < nums.length`
+* 1 <= queries[i][1] <= 105
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/readme.md b/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/readme.md
new file mode 100644
index 000000000..bcbc98bf6
--- /dev/null
+++ b/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/readme.md
@@ -0,0 +1,106 @@
+3570\. Find Books with No Available Copies
+
+Easy
+
+Table: `library_books`
+
+ +------------------+---------+
+ | Column Name | Type |
+ +------------------+---------+
+ | book_id | int |
+ | title | varchar |
+ | author | varchar |
+ | genre | varchar |
+ | publication_year | int |
+ | total_copies | int |
+ +------------------+---------+
+ book_id is the unique identifier for this table.
+ Each row contains information about a book in the library, including the total number of copies owned by the library.
+
+Table: `borrowing_records`
+
+ +---------------+---------+
+ | Column Name | Type |
+ |----------------|---------|
+ | record_id | int |
+ | book_id | int |
+ | borrower_name | varchar |
+ | borrow_date | date |
+ | return_date | date |
+ +----------------+---------+
+ record_id is the unique identifier for this table.
+ Each row represents a borrowing transaction and return_date is NULL if the book is currently borrowed and hasn't been returned yet.
+
+Write a solution to find **all books** that are **currently borrowed (not returned)** and have **zero copies available** in the library.
+
+* A book is considered **currently borrowed** if there exists a borrowing record with a **NULL** `return_date`
+
+Return _the result table ordered by current borrowers in **descending** order, then by book title in **ascending** order._
+
+The result format is in the following example.
+
+**Example:**
+
+**Input:**
+
+library\_books table:
+
+ +---------+--------------------------+----------------+-----------+------------------+--------------+
+ | book_id | Title | Author | Genre | Publication Year | Total Copies |
+ |---------|--------------------------|----------------|-----------|------------------|--------------|
+ | 1 | The Great Gatsby | F. Scott | Fiction | 1925 | 3 |
+ | 2 | To Kill a Mockingbird | Harper Lee | Fiction | 1960 | 3 |
+ | 3 | 1984 | George Orwell | Dystopian | 1949 | 1 |
+ | 4 | Pride and Prejudice | Jane Austen | Romance | 1813 | 2 |
+ | 5 | The Catcher in the Rye | J.D. Salinger | Fiction | 1951 | 1 |
+ | 6 | Brave New World | Aldous Huxley | Dystopian | 1932 | 4 |
+ +---------+--------------------------+----------------+-----------+------------------+--------------+
+
+borrowing\_records table:
+
+ +-----------+---------+---------------+-------------+-------------+
+ | record_id | book_id | borrower_name | borrow_date | return_date |
+ |-----------|---------|---------------|-------------|-------------|
+ | 1 | 1 | Alice Smith | 2024-01-15 | NULL |
+ | 2 | 1 | Bob Johnson | 2024-01-20 | NULL |
+ | 3 | 2 | Carol White | 2024-01-10 | 2024-01-25 |
+ | 4 | 3 | David Brown | 2024-02-01 | NULL |
+ | 5 | 4 | Emma Wilson | 2024-01-05 | NULL |
+ | 6 | 5 | Frank Davis | 2024-01-18 | 2024-02-10 |
+ | 7 | 1 | Grace Miller | 2024-02-05 | NULL |
+ | 8 | 6 | Henry Taylor | 2024-01-12 | NULL |
+ | 9 | 2 | Ivan Clark | 2024-02-12 | NULL |
+ | 10 | 2 | Jane Adams | 2024-02-15 | NULL |
+ +-----------+---------+---------------+-------------+-------------+
+
+**Output:**
+
+ +---------+-------------------+----------------+-----------+------------------+-------------------+
+ | book_id | Title | Author | Genre | Publication Year | Current Borrowers |
+ |---------|-------------------|----------------|-----------|------------------|-------------------|
+ | 1 | The Great Gatsby | F. Scott | Fiction | 1925 | 3 |
+ | 3 | 1984 | George Orwell | Dystopian | 1949 | 1 |
+ +---------+-------------------+----------------+-----------+------------------+-------------------+
+
+**Explanation:**
+
+* **The Great Gatsby (book\_id = 1):**
+ * Total copies: 3
+ * Currently borrowed by Alice Smith, Bob Johnson, and Grace Miller (3 borrowers)
+ * Available copies: 3 - 3 = 0
+ * Included because available\_copies = 0
+* **1984 (book\_id = 3):**
+ * Total copies: 1
+ * Currently borrowed by David Brown (1 borrower)
+ * Available copies: 1 - 1 = 0
+ * Included because available\_copies = 0
+* **Books not included:**
+ * To Kill a Mockingbird (book\_id = 2): Total copies = 3, current borrowers = 2, available = 1
+ * Pride and Prejudice (book\_id = 4): Total copies = 2, current borrowers = 1, available = 1
+ * The Catcher in the Rye (book\_id = 5): Total copies = 1, current borrowers = 0, available = 1
+ * Brave New World (book\_id = 6): Total copies = 4, current borrowers = 1, available = 3
+* **Result ordering:**
+ * The Great Gatsby appears first with 3 current borrowers
+ * 1984 appears second with 1 current borrower
+
+Output table is ordered by current\_borrowers in descending order, then by book\_title in ascending order.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/script.sql b/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/script.sql
new file mode 100644
index 000000000..db34b0ea7
--- /dev/null
+++ b/src/main/java/g3501_3600/s3570_find_books_with_no_available_copies/script.sql
@@ -0,0 +1,38 @@
+# Write your MySQL query statement below
+# #Easy #Database #2025_06_03_Time_512_ms_(100.00%)_Space_0.0_MB_(100.00%)
+SELECT
+ book_id,
+ MAX(title) AS title,
+ MAX(author) AS author,
+ MAX(genre) AS genre,
+ MAX(publication_year) AS publication_year,
+ MAX(total_copies) AS current_borrowers
+FROM (
+ SELECT
+ book_id,
+ title,
+ author,
+ genre,
+ publication_year,
+ total_copies,
+ total_copies AS total_remain
+ FROM library_books
+ UNION ALL
+ SELECT
+ book_id,
+ '' AS title,
+ '' AS author,
+ '' AS genre,
+ 1000 AS publication_year,
+ 0 AS total_copies,
+ -1 AS total_remain
+ FROM borrowing_records
+ WHERE return_date IS NULL
+) AS sub
+GROUP BY
+ book_id
+HAVING
+ SUM(total_remain) = 0
+ORDER BY
+ current_borrowers DESC,
+ title ASC;
diff --git a/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java
new file mode 100644
index 000000000..56842a60f
--- /dev/null
+++ b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java
@@ -0,0 +1,45 @@
+package g3501_3600.s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues;
+
+// #Medium #Array #Hash_Table #Sorting #Greedy #Heap_Priority_Queue
+// #2025_06_10_Time_2_ms_(100.00%)_Space_64.25_MB_(40.62%)
+
+public class Solution {
+ public int maxSumDistinctTriplet(int[] x, int[] y) {
+ int index = -1;
+ int max = -1;
+ int sum = 0;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max) {
+ max = y[i];
+ index = i;
+ }
+ }
+ sum += max;
+ if (max == -1) {
+ return -1;
+ }
+ int index2 = -1;
+ max = -1;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max && x[i] != x[index]) {
+ max = y[i];
+ index2 = i;
+ }
+ }
+ sum += max;
+ if (max == -1) {
+ return -1;
+ }
+ max = -1;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max && x[i] != x[index] && x[i] != x[index2]) {
+ max = y[i];
+ }
+ }
+ if (max == -1) {
+ return -1;
+ }
+ sum += max;
+ return sum;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md
new file mode 100644
index 000000000..3c88dbe58
--- /dev/null
+++ b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md
@@ -0,0 +1,40 @@
+3572\. Maximize Y‑Sum by Picking a Triplet of Distinct X‑Values
+
+Medium
+
+You are given two integer arrays `x` and `y`, each of length `n`. You must choose three **distinct** indices `i`, `j`, and `k` such that:
+
+* `x[i] != x[j]`
+* `x[j] != x[k]`
+* `x[k] != x[i]`
+
+Your goal is to **maximize** the value of `y[i] + y[j] + y[k]` under these conditions. Return the **maximum** possible sum that can be obtained by choosing such a triplet of indices.
+
+If no such triplet exists, return -1.
+
+**Example 1:**
+
+**Input:** x = [1,2,1,3,2], y = [5,3,4,6,2]
+
+**Output:** 14
+
+**Explanation:**
+
+* Choose `i = 0` (`x[i] = 1`, `y[i] = 5`), `j = 1` (`x[j] = 2`, `y[j] = 3`), `k = 3` (`x[k] = 3`, `y[k] = 6`).
+* All three values chosen from `x` are distinct. `5 + 3 + 6 = 14` is the maximum we can obtain. Hence, the output is 14.
+
+**Example 2:**
+
+**Input:** x = [1,2,1,2], y = [4,5,6,7]
+
+**Output:** \-1
+
+**Explanation:**
+
+* There are only two distinct values in `x`. Hence, the output is -1.
+
+**Constraints:**
+
+* `n == x.length == y.length`
+* 3 <= n <= 105
+* 1 <= x[i], y[i] <= 106
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java
new file mode 100644
index 000000000..36cbfa748
--- /dev/null
+++ b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java
@@ -0,0 +1,28 @@
+package g3501_3600.s3573_best_time_to_buy_and_sell_stock_v;
+
+// #Medium #Array #Dynamic_Programming #2025_06_10_Time_10_ms_(99.46%)_Space_44.46_MB_(97.36%)
+
+public class Solution {
+ public long maximumProfit(int[] prices, int k) {
+ int n = prices.length;
+ long[] prev = new long[n];
+ long[] curr = new long[n];
+ for (int t = 1; t <= k; t++) {
+ long bestLong = -prices[0];
+ long bestShort = prices[0];
+ curr[0] = 0;
+ for (int i = 1; i < n; i++) {
+ long res = curr[i - 1];
+ res = Math.max(res, prices[i] + bestLong);
+ res = Math.max(res, -prices[i] + bestShort);
+ curr[i] = res;
+ bestLong = Math.max(bestLong, prev[i - 1] - prices[i]);
+ bestShort = Math.max(bestShort, prev[i - 1] + prices[i]);
+ }
+ long[] tmp = prev;
+ prev = curr;
+ curr = tmp;
+ }
+ return prev[n - 1];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md
new file mode 100644
index 000000000..89e19ab66
--- /dev/null
+++ b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md
@@ -0,0 +1,49 @@
+3573\. Best Time to Buy and Sell Stock V
+
+Medium
+
+You are given an integer array `prices` where `prices[i]` is the price of a stock in dollars on the ith
day, and an integer `k`.
+
+You are allowed to make at most `k` transactions, where each transaction can be either of the following:
+
+* **Normal transaction**: Buy on day `i`, then sell on a later day `j` where `i < j`. You profit `prices[j] - prices[i]`.
+
+* **Short selling transaction**: Sell on day `i`, then buy back on a later day `j` where `i < j`. You profit `prices[i] - prices[j]`.
+
+
+**Note** that you must complete each transaction before starting another. Additionally, you can't buy or sell on the same day you are selling or buying back as part of a previous transaction.
+
+Return the **maximum** total profit you can earn by making **at most** `k` transactions.
+
+**Example 1:**
+
+**Input:** prices = [1,7,9,8,2], k = 2
+
+**Output:** 14
+
+**Explanation:**
+
+We can make $14 of profit through 2 transactions:
+
+* A normal transaction: buy the stock on day 0 for $1 then sell it on day 2 for $9.
+* A short selling transaction: sell the stock on day 3 for $8 then buy back on day 4 for $2.
+
+**Example 2:**
+
+**Input:** prices = [12,16,19,19,8,1,19,13,9], k = 3
+
+**Output:** 36
+
+**Explanation:**
+
+We can make $36 of profit through 3 transactions:
+
+* A normal transaction: buy the stock on day 0 for $12 then sell it on day 2 for $19.
+* A short selling transaction: sell the stock on day 3 for $19 then buy back on day 4 for $8.
+* A normal transaction: buy the stock on day 5 for $1 then sell it on day 6 for $19.
+
+**Constraints:**
+
+* 2 <= prices.length <= 103
+* 1 <= prices[i] <= 109
+* `1 <= k <= prices.length / 2`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java
new file mode 100644
index 000000000..4e95f3971
--- /dev/null
+++ b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java
@@ -0,0 +1,69 @@
+package g3501_3600.s3574_maximize_subarray_gcd_score;
+
+// #Hard #Array #Math #Enumeration #Number_Theory
+// #2025_06_10_Time_13_ms_(100.00%)_Space_45.07_MB_(78.08%)
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unchecked")
+public class Solution {
+ public long maxGCDScore(int[] nums, int k) {
+ int mx = 0;
+ for (int x : nums) {
+ mx = Math.max(mx, x);
+ }
+ int width = 32 - Integer.numberOfLeadingZeros(mx);
+ List[] lowbitPos = new List[width];
+ Arrays.setAll(lowbitPos, i -> new ArrayList<>());
+ int[][] intervals = new int[width + 1][3];
+ int size = 0;
+ long ans = 0;
+ for (int i = 0; i < nums.length; i++) {
+ int x = nums[i];
+ int tz = Integer.numberOfTrailingZeros(x);
+ lowbitPos[tz].add(i);
+ for (int j = 0; j < size; j++) {
+ intervals[j][0] = gcd(intervals[j][0], x);
+ }
+ intervals[size][0] = x;
+ intervals[size][1] = i - 1;
+ intervals[size][2] = i;
+ size++;
+ int idx = 1;
+ for (int j = 1; j < size; j++) {
+ if (intervals[j][0] != intervals[j - 1][0]) {
+ intervals[idx][0] = intervals[j][0];
+ intervals[idx][1] = intervals[j][1];
+ intervals[idx][2] = intervals[j][2];
+ idx++;
+ } else {
+ intervals[idx - 1][2] = intervals[j][2];
+ }
+ }
+ size = idx;
+ for (int j = 0; j < size; j++) {
+ int g = intervals[j][0];
+ int l = intervals[j][1];
+ int r = intervals[j][2];
+ ans = Math.max(ans, (long) g * (i - l));
+ List pos = lowbitPos[Integer.numberOfTrailingZeros(g)];
+ int minL = pos.size() > k ? Math.max(l, pos.get(pos.size() - k - 1)) : l;
+ if (minL < r) {
+ ans = Math.max(ans, (long) g * 2 * (i - minL));
+ }
+ }
+ }
+ return ans;
+ }
+
+ private int gcd(int a, int b) {
+ while (a != 0) {
+ int tmp = a;
+ a = b % a;
+ b = tmp;
+ }
+ return b;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md
new file mode 100644
index 000000000..09b9789ec
--- /dev/null
+++ b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md
@@ -0,0 +1,56 @@
+3574\. Maximize Subarray GCD Score
+
+Hard
+
+You are given an array of positive integers `nums` and an integer `k`.
+
+You may perform at most `k` operations. In each operation, you can choose one element in the array and **double** its value. Each element can be doubled **at most** once.
+
+The **score** of a contiguous **subarray** is defined as the **product** of its length and the _greatest common divisor (GCD)_ of all its elements.
+
+Your task is to return the **maximum** **score** that can be achieved by selecting a contiguous subarray from the modified array.
+
+**Note:**
+
+* The **greatest common divisor (GCD)** of an array is the largest integer that evenly divides all the array elements.
+
+**Example 1:**
+
+**Input:** nums = [2,4], k = 1
+
+**Output:** 8
+
+**Explanation:**
+
+* Double `nums[0]` to 4 using one operation. The modified array becomes `[4, 4]`.
+* The GCD of the subarray `[4, 4]` is 4, and the length is 2.
+* Thus, the maximum possible score is `2 × 4 = 8`.
+
+**Example 2:**
+
+**Input:** nums = [3,5,7], k = 2
+
+**Output:** 14
+
+**Explanation:**
+
+* Double `nums[2]` to 14 using one operation. The modified array becomes `[3, 5, 14]`.
+* The GCD of the subarray `[14]` is 14, and the length is 1.
+* Thus, the maximum possible score is `1 × 14 = 14`.
+
+**Example 3:**
+
+**Input:** nums = [5,5,5], k = 1
+
+**Output:** 15
+
+**Explanation:**
+
+* The subarray `[5, 5, 5]` has a GCD of 5, and its length is 3.
+* Since doubling any element doesn't improve the score, the maximum score is `3 × 5 = 15`.
+
+**Constraints:**
+
+* `1 <= n == nums.length <= 1500`
+* 1 <= nums[i] <= 109
+* `1 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java
new file mode 100644
index 000000000..0d51fce52
--- /dev/null
+++ b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java
@@ -0,0 +1,85 @@
+package g3501_3600.s3575_maximum_good_subtree_score;
+
+// #Hard #Array #Dynamic_Programming #Depth_First_Search #Tree #Bit_Manipulation #Bitmask
+// #2025_06_10_Time_92_ms_(98.73%)_Space_55.23_MB_(11.71%)
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unchecked")
+public class Solution {
+ private int digits = 10;
+ private int full = 1 << digits;
+ private long neg = Long.MIN_VALUE / 4;
+ private long mod = (long) 1e9 + 7;
+ private List[] tree;
+ private int[] val;
+ private int[] mask;
+ private boolean[] isOk;
+ private long res = 0;
+
+ public int goodSubtreeSum(int[] vals, int[] par) {
+ int n = vals.length;
+ val = vals;
+ mask = new int[n];
+ isOk = new boolean[n];
+ for (int i = 0; i < n; i++) {
+ int m = 0;
+ int v = vals[i];
+ boolean valid = true;
+ while (v > 0) {
+ int d = v % 10;
+ if (((m >> d) & 1) == 1) {
+ valid = false;
+ break;
+ }
+ m |= 1 << d;
+ v /= 10;
+ }
+ mask[i] = m;
+ isOk[i] = valid;
+ }
+ tree = new ArrayList[n];
+ Arrays.setAll(tree, ArrayList::new);
+ int root = 0;
+ for (int i = 1; i < n; i++) {
+ tree[par[i]].add(i);
+ }
+ dfs(root);
+ return (int) (res % mod);
+ }
+
+ private long[] dfs(int u) {
+ long[] dp = new long[full];
+ Arrays.fill(dp, neg);
+ dp[0] = 0;
+ if (isOk[u]) {
+ dp[mask[u]] = val[u];
+ }
+ for (int v : tree[u]) {
+ long[] child = dfs(v);
+ long[] newDp = Arrays.copyOf(dp, full);
+ for (int m1 = 0; m1 < full; m1++) {
+ if (dp[m1] < 0) {
+ continue;
+ }
+ int remain = full - 1 - m1;
+ for (int m2 = remain; m2 > 0; m2 = (m2 - 1) & remain) {
+ if (child[m2] < 0) {
+ continue;
+ }
+ int newM = m1 | m2;
+ newDp[newM] = Math.max(newDp[newM], dp[m1] + child[m2]);
+ }
+ }
+ dp = newDp;
+ }
+ long best = 0;
+ for (long v : dp) {
+ best = Math.max(best, v);
+ }
+ res = (res + best) % mod;
+ return dp;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md
new file mode 100644
index 000000000..bb1a07b9c
--- /dev/null
+++ b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md
@@ -0,0 +1,81 @@
+3575\. Maximum Good Subtree Score
+
+Hard
+
+You are given an undirected tree rooted at node 0 with `n` nodes numbered from 0 to `n - 1`. Each node `i` has an integer value `vals[i]`, and its parent is given by `par[i]`.
+
+A **subset** of nodes within the **subtree** of a node is called **good** if every digit from 0 to 9 appears **at most** once in the decimal representation of the values of the selected nodes.
+
+The **score** of a good subset is the sum of the values of its nodes.
+
+Define an array `maxScore` of length `n`, where `maxScore[u]` represents the **maximum** possible sum of values of a good subset of nodes that belong to the subtree rooted at node `u`, including `u` itself and all its descendants.
+
+Return the sum of all values in `maxScore`.
+
+Since the answer may be large, return it **modulo** 109 + 7
.
+
+**Example 1:**
+
+**Input:** vals = [2,3], par = [-1,0]
+
+**Output:** 8
+
+**Explanation:**
+
+
+
+* The subtree rooted at node 0 includes nodes `{0, 1}`. The subset `{2, 3}` is good as the digits 2 and 3 appear only once. The score of this subset is `2 + 3 = 5`.
+* The subtree rooted at node 1 includes only node `{1}`. The subset `{3}` is good. The score of this subset is 3.
+* The `maxScore` array is `[5, 3]`, and the sum of all values in `maxScore` is `5 + 3 = 8`. Thus, the answer is 8.
+
+**Example 2:**
+
+**Input:** vals = [1,5,2], par = [-1,0,0]
+
+**Output:** 15
+
+**Explanation:**
+
+****
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{1, 5, 2}` is good as the digits 1, 5 and 2 appear only once. The score of this subset is `1 + 5 + 2 = 8`.
+* The subtree rooted at node 1 includes only node `{1}`. The subset `{5}` is good. The score of this subset is 5.
+* The subtree rooted at node 2 includes only node `{2}`. The subset `{2}` is good. The score of this subset is 2.
+* The `maxScore` array is `[8, 5, 2]`, and the sum of all values in `maxScore` is `8 + 5 + 2 = 15`. Thus, the answer is 15.
+
+**Example 3:**
+
+**Input:** vals = [34,1,2], par = [-1,0,1]
+
+**Output:** 42
+
+**Explanation:**
+
+
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{34, 1, 2}` is good as the digits 3, 4, 1 and 2 appear only once. The score of this subset is `34 + 1 + 2 = 37`.
+* The subtree rooted at node 1 includes node `{1, 2}`. The subset `{1, 2}` is good as the digits 1 and 2 appear only once. The score of this subset is `1 + 2 = 3`.
+* The subtree rooted at node 2 includes only node `{2}`. The subset `{2}` is good. The score of this subset is 2.
+* The `maxScore` array is `[37, 3, 2]`, and the sum of all values in `maxScore` is `37 + 3 + 2 = 42`. Thus, the answer is 42.
+
+**Example 4:**
+
+**Input:** vals = [3,22,5], par = [-1,0,1]
+
+**Output:** 18
+
+**Explanation:**
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{3, 22, 5}` is not good, as digit 2 appears twice. Therefore, the subset `{3, 5}` is valid. The score of this subset is `3 + 5 = 8`.
+* The subtree rooted at node 1 includes nodes `{1, 2}`. The subset `{22, 5}` is not good, as digit 2 appears twice. Therefore, the subset `{5}` is valid. The score of this subset is 5.
+* The subtree rooted at node 2 includes `{2}`. The subset `{5}` is good. The score of this subset is 5.
+* The `maxScore` array is `[8, 5, 5]`, and the sum of all values in `maxScore` is `8 + 5 + 5 = 18`. Thus, the answer is 18.
+
+**Constraints:**
+
+* `1 <= n == vals.length <= 500`
+* 1 <= vals[i] <= 109
+* `par.length == n`
+* `par[0] == -1`
+* `0 <= par[i] < n` for `i` in `[1, n - 1]`
+* The input is generated such that the parent array `par` represents a valid tree.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java
new file mode 100644
index 000000000..4c1a7dcee
--- /dev/null
+++ b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java
@@ -0,0 +1,44 @@
+package g3501_3600.s3576_transform_array_to_all_equal_elements;
+
+// #Medium #Array #Greedy #2025_06_10_Time_7_ms_(99.81%)_Space_56.56_MB_(99.57%)
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Solution {
+ public boolean canMakeEqual(int[] nums, int k) {
+ int n = nums.length;
+ if (n == 1) {
+ return true;
+ }
+ int prod = 1;
+ for (int x : nums) {
+ prod *= x;
+ }
+ List targets = new ArrayList<>();
+ for (int target : new int[] {1, -1}) {
+ int tPowN = (n % 2 == 0 ? 1 : target);
+ if (tPowN == prod) {
+ targets.add(target);
+ }
+ }
+ if (targets.isEmpty()) {
+ return false;
+ }
+ for (int target : targets) {
+ int ops = 0;
+ int[] a = nums.clone();
+ for (int i = 0; i < n - 1 && ops <= k; i++) {
+ if (a[i] != target) {
+ a[i] = -a[i];
+ a[i + 1] = -a[i + 1];
+ ops++;
+ }
+ }
+ if (ops <= k && a[n - 1] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md
new file mode 100644
index 000000000..61c7d3948
--- /dev/null
+++ b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md
@@ -0,0 +1,43 @@
+3576\. Transform Array to All Equal Elements
+
+Medium
+
+You are given an integer array `nums` of size `n` containing only `1` and `-1`, and an integer `k`.
+
+You can perform the following operation at most `k` times:
+
+* Choose an index `i` (`0 <= i < n - 1`), and **multiply** both `nums[i]` and `nums[i + 1]` by `-1`.
+
+
+**Note** that you can choose the same index `i` more than once in **different** operations.
+
+Return `true` if it is possible to make all elements of the array **equal** after at most `k` operations, and `false` otherwise.
+
+**Example 1:**
+
+**Input:** nums = [1,-1,1,-1,1], k = 3
+
+**Output:** true
+
+**Explanation:**
+
+We can make all elements in the array equal in 2 operations as follows:
+
+* Choose index `i = 1`, and multiply both `nums[1]` and `nums[2]` by -1. Now `nums = [1,1,-1,-1,1]`.
+* Choose index `i = 2`, and multiply both `nums[2]` and `nums[3]` by -1. Now `nums = [1,1,1,1,1]`.
+
+**Example 2:**
+
+**Input:** nums = [-1,-1,-1,1,1,1], k = 5
+
+**Output:** false
+
+**Explanation:**
+
+It is not possible to make all array elements equal in at most 5 operations.
+
+**Constraints:**
+
+* 1 <= n == nums.length <= 105
+* `nums[i]` is either -1 or 1.
+* `1 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java
new file mode 100644
index 000000000..6a5944a5a
--- /dev/null
+++ b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java
@@ -0,0 +1,22 @@
+package g3501_3600.s3577_count_the_number_of_computer_unlocking_permutations;
+
+// #Medium #Array #Math #Combinatorics #Brainteaser
+// #2025_06_10_Time_1_ms_(100.00%)_Space_62.24_MB_(22.08%)
+
+public class Solution {
+ private static final int MOD = 1_000_000_007;
+
+ public int countPermutations(int[] complexity) {
+ int n = complexity.length;
+ for (int i = 1; i < n; i++) {
+ if (complexity[i] <= complexity[0]) {
+ return 0;
+ }
+ }
+ long ans = 1;
+ for (int x = 2; x < n; x++) {
+ ans = (ans * x) % MOD;
+ }
+ return (int) ans;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md
new file mode 100644
index 000000000..8bc0a14cc
--- /dev/null
+++ b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md
@@ -0,0 +1,52 @@
+3577\. Count the Number of Computer Unlocking Permutations
+
+Medium
+
+You are given an array `complexity` of length `n`.
+
+There are `n` **locked** computers in a room with labels from 0 to `n - 1`, each with its own **unique** password. The password of the computer `i` has a complexity `complexity[i]`.
+
+The password for the computer labeled 0 is **already** decrypted and serves as the root. All other computers must be unlocked using it or another previously unlocked computer, following this information:
+
+* You can decrypt the password for the computer `i` using the password for computer `j`, where `j` is **any** integer less than `i` with a lower complexity. (i.e. `j < i` and `complexity[j] < complexity[i]`)
+* To decrypt the password for computer `i`, you must have already unlocked a computer `j` such that `j < i` and `complexity[j] < complexity[i]`.
+
+Find the number of permutations of `[0, 1, 2, ..., (n - 1)]` that represent a valid order in which the computers can be unlocked, starting from computer 0 as the only initially unlocked one.
+
+Since the answer may be large, return it **modulo** 109 + 7.
+
+**Note** that the password for the computer **with label** 0 is decrypted, and _not_ the computer with the first position in the permutation.
+
+**Example 1:**
+
+**Input:** complexity = [1,2,3]
+
+**Output:** 2
+
+**Explanation:**
+
+The valid permutations are:
+
+* [0, 1, 2]
+ * Unlock computer 0 first with root password.
+ * Unlock computer 1 with password of computer 0 since `complexity[0] < complexity[1]`.
+ * Unlock computer 2 with password of computer 1 since `complexity[1] < complexity[2]`.
+* [0, 2, 1]
+ * Unlock computer 0 first with root password.
+ * Unlock computer 2 with password of computer 0 since `complexity[0] < complexity[2]`.
+ * Unlock computer 1 with password of computer 0 since `complexity[0] < complexity[1]`.
+
+**Example 2:**
+
+**Input:** complexity = [3,3,3,4,4,4]
+
+**Output:** 0
+
+**Explanation:**
+
+There are no possible permutations which can unlock all computers.
+
+**Constraints:**
+
+* 2 <= complexity.length <= 105
+* 1 <= complexity[i] <= 109
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java
new file mode 100644
index 000000000..bec158796
--- /dev/null
+++ b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java
@@ -0,0 +1,49 @@
+package g3501_3600.s3578_count_partitions_with_max_min_difference_at_most_k;
+
+// #Medium #Array #Dynamic_Programming #Prefix_Sum #Sliding_Window #Queue #Monotonic_Queue
+// #2025_06_10_Time_16_ms_(99.88%)_Space_55.12_MB_(98.72%)
+
+public class Solution {
+ private static final int MOD = 1_000_000_007;
+
+ public int countPartitions(int[] nums, int k) {
+ int n = nums.length;
+ int[] dp = new int[n + 1];
+ dp[0] = 1;
+ int[] prefix = new int[n + 1];
+ prefix[0] = 1;
+ int[] maxDeque = new int[n];
+ int maxFront = 0;
+ int maxBack = 0;
+ int[] minDeque = new int[n];
+ int minFront = 0;
+ int minBack = 0;
+ int start = 0;
+ for (int end = 0; end < n; end++) {
+ while (maxBack > maxFront && nums[maxDeque[maxBack - 1]] <= nums[end]) {
+ maxBack--;
+ }
+ maxDeque[maxBack++] = end;
+ while (minBack > minFront && nums[minDeque[minBack - 1]] >= nums[end]) {
+ minBack--;
+ }
+ minDeque[minBack++] = end;
+ while (nums[maxDeque[maxFront]] - nums[minDeque[minFront]] > k) {
+ if (maxDeque[maxFront] == start) {
+ maxFront++;
+ }
+ if (minDeque[minFront] == start) {
+ minFront++;
+ }
+ start++;
+ }
+ int sum = prefix[end] - (start > 0 ? prefix[start - 1] : 0);
+ if (sum < 0) {
+ sum += MOD;
+ }
+ dp[end + 1] = sum % MOD;
+ prefix[end + 1] = (prefix[end] + dp[end + 1]) % MOD;
+ }
+ return dp[n];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md
new file mode 100644
index 000000000..7bb809d52
--- /dev/null
+++ b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md
@@ -0,0 +1,45 @@
+3578\. Count Partitions With Max-Min Difference at Most K
+
+Medium
+
+You are given an integer array `nums` and an integer `k`. Your task is to partition `nums` into one or more **non-empty** contiguous segments such that in each segment, the difference between its **maximum** and **minimum** elements is **at most** `k`.
+
+Return the total number of ways to partition `nums` under this condition.
+
+Since the answer may be too large, return it **modulo** 109 + 7
.
+
+**Example 1:**
+
+**Input:** nums = [9,4,1,3,7], k = 4
+
+**Output:** 6
+
+**Explanation:**
+
+There are 6 valid partitions where the difference between the maximum and minimum elements in each segment is at most `k = 4`:
+
+* `[[9], [4], [1], [3], [7]]`
+* `[[9], [4], [1], [3, 7]]`
+* `[[9], [4], [1, 3], [7]]`
+* `[[9], [4, 1], [3], [7]]`
+* `[[9], [4, 1], [3, 7]]`
+* `[[9], [4, 1, 3], [7]]`
+
+**Example 2:**
+
+**Input:** nums = [3,3,4], k = 0
+
+**Output:** 2
+
+**Explanation:**
+
+There are 2 valid partitions that satisfy the given conditions:
+
+* `[[3], [3], [4]]`
+* `[[3, 3], [4]]`
+
+**Constraints:**
+
+* 2 <= nums.length <= 5 * 104
+* 1 <= nums[i] <= 109
+* 0 <= k <= 109
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java
new file mode 100644
index 000000000..2e4ffbee7
--- /dev/null
+++ b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java
@@ -0,0 +1,47 @@
+package g3501_3600.s3579_minimum_steps_to_convert_string_with_operations;
+
+// #Hard #String #Dynamic_Programming #Greedy
+// #2025_06_10_Time_50_ms_(98.37%)_Space_45.06_MB_(98.37%)
+
+public class Solution {
+ public int minOperations(String word1, String word2) {
+ int[] dp = new int[word1.length()];
+ int[][] count = new int[26][26];
+ for (int i = 0; i < word1.length(); i++) {
+ dp[i] = Integer.MAX_VALUE;
+ }
+ for (int i = 0; i < word1.length(); i++) {
+ for (int j = i; j >= 0; j--) {
+ int c1 = 0;
+ int c2 = 0;
+ for (int k1 = j, k2 = j; k1 <= i && k2 <= i; k1++, k2++) {
+ int[] ints = count[word2.charAt(k2) - 'a'];
+ if (ints[word1.charAt(k1) - 'a'] > 0) {
+ ints[word1.charAt(k1) - 'a']--;
+ } else if (word1.charAt(k1) != word2.charAt(k2)) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a']++;
+ c1++;
+ }
+ }
+ for (int k1 = j, k2 = j; k1 <= i && k2 <= i; k1++, k2++) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a'] = 0;
+ }
+ dp[i] = Math.min(dp[i], j - 1 < 0 ? c1 : dp[j - 1] + c1);
+ for (int k1 = j, k2 = i; k1 <= i && k2 >= j; k1++, k2--) {
+ int[] ints = count[word2.charAt(k2) - 'a'];
+ if (ints[word1.charAt(k1) - 'a'] > 0) {
+ ints[word1.charAt(k1) - 'a']--;
+ } else if (word1.charAt(k1) - 'a' != word2.charAt(k2) - 'a') {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a']++;
+ c2++;
+ }
+ }
+ for (int k1 = j, k2 = i; k1 <= i && k2 >= j; k1++, k2--) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a'] = 0;
+ }
+ dp[i] = Math.min(dp[i], j - 1 < 0 ? c2 + 1 : dp[j - 1] + c2 + 1);
+ }
+ }
+ return dp[word1.length() - 1];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md
new file mode 100644
index 000000000..daca34910
--- /dev/null
+++ b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md
@@ -0,0 +1,73 @@
+3579\. Minimum Steps to Convert String with Operations
+
+Hard
+
+You are given two strings, `word1` and `word2`, of equal length. You need to transform `word1` into `word2`.
+
+For this, divide `word1` into one or more **contiguous **substring****. For each substring `substr` you can perform the following operations:
+
+1. **Replace:** Replace the character at any one index of `substr` with another lowercase English letter.
+
+2. **Swap:** Swap any two characters in `substr`.
+
+3. **Reverse Substring:** Reverse `substr`.
+
+
+Each of these counts as **one** operation and each character of each substring can be used in each type of operation at most once (i.e. no single index may be involved in more than one replace, one swap, or one reverse).
+
+Return the **minimum number of operations** required to transform `word1` into `word2`.
+
+**Example 1:**
+
+**Input:** word1 = "abcdf", word2 = "dacbe"
+
+**Output:** 4
+
+**Explanation:**
+
+Divide `word1` into `"ab"`, `"c"`, and `"df"`. The operations are:
+
+* For the substring `"ab"`,
+ * Perform operation of type 3 on `"ab" -> "ba"`.
+ * Perform operation of type 1 on `"ba" -> "da"`.
+* For the substring `"c"` do no operations.
+* For the substring `"df"`,
+ * Perform operation of type 1 on `"df" -> "bf"`.
+ * Perform operation of type 1 on `"bf" -> "be"`.
+
+**Example 2:**
+
+**Input:** word1 = "abceded", word2 = "baecfef"
+
+**Output:** 4
+
+**Explanation:**
+
+Divide `word1` into `"ab"`, `"ce"`, and `"ded"`. The operations are:
+
+* For the substring `"ab"`,
+ * Perform operation of type 2 on `"ab" -> "ba"`.
+* For the substring `"ce"`,
+ * Perform operation of type 2 on `"ce" -> "ec"`.
+* For the substring `"ded"`,
+ * Perform operation of type 1 on `"ded" -> "fed"`.
+ * Perform operation of type 1 on `"fed" -> "fef"`.
+
+**Example 3:**
+
+**Input:** word1 = "abcdef", word2 = "fedabc"
+
+**Output:** 2
+
+**Explanation:**
+
+Divide `word1` into `"abcdef"`. The operations are:
+
+* For the substring `"abcdef"`,
+ * Perform operation of type 3 on `"abcdef" -> "fedcba"`.
+ * Perform operation of type 2 on `"fedcba" -> "fedabc"`.
+
+**Constraints:**
+
+* `1 <= word1.length == word2.length <= 100`
+* `word1` and `word2` consist only of lowercase English letters.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/readme.md b/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/readme.md
new file mode 100644
index 000000000..2bc35eb87
--- /dev/null
+++ b/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/readme.md
@@ -0,0 +1,112 @@
+3580\. Find Consistently Improving Employees
+
+Medium
+
+Table: `employees`
+
+ +-------------+---------+
+ | Column Name | Type |
+ +-------------+---------+
+ | employee_id | int |
+ | name | varchar |
+ +-------------+---------+
+ employee_id is the unique identifier for this table.
+ Each row contains information about an employee.
+
+Table: `performance_reviews`
+
+ +-------------+------+
+ | Column Name | Type |
+ +-------------+------+
+ | review_id | int |
+ | employee_id | int |
+ | review_date | date |
+ | rating | int |
+ +-------------+------+
+ review_id is the unique identifier for this table.
+ Each row represents a performance review for an employee.
+ The rating is on a scale of 1-5 where 5 is excellent and 1 is poor.
+
+Write a solution to find employees who have consistently improved their performance over **their last three reviews**.
+
+* An employee must have **at least** `3` **review** to be considered
+* The employee's **last** `3` **reviews** must show **strictly increasing ratings** (each review better than the previous)
+* Use the most recent `3` reviews based on `review_date` for each employee
+* Calculate the **improvement score** as the difference between the latest rating and the earliest rating among the last `3` reviews
+
+Return _the result table ordered by **improvement score** in **descending** order, then by **name** in **ascending** order_.
+
+The result format is in the following example.
+
+**Example:**
+
+**Input:**
+
+employees table:
+
+ +-------------+----------------+
+ | employee_id | name |
+ +-------------+----------------+
+ | 1 | Alice Johnson |
+ | 2 | Bob Smith |
+ | 3 | Carol Davis |
+ | 4 | David Wilson |
+ | 5 | Emma Brown |
+ +-------------+----------------+
+
+performance\_reviews table:
+
+ +-----------+-------------+-------------+--------+
+ | review_id | employee_id | review_date | rating |
+ +-----------+-------------+-------------+--------+
+ | 1 | 1 | 2023-01-15 | 2 |
+ | 2 | 1 | 2023-04-15 | 3 |
+ | 3 | 1 | 2023-07-15 | 4 |
+ | 4 | 1 | 2023-10-15 | 5 |
+ | 5 | 2 | 2023-02-01 | 3 |
+ | 6 | 2 | 2023-05-01 | 2 |
+ | 7 | 2 | 2023-08-01 | 4 |
+ | 8 | 2 | 2023-11-01 | 5 |
+ | 9 | 3 | 2023-03-10 | 1 |
+ | 10 | 3 | 2023-06-10 | 2 |
+ | 11 | 3 | 2023-09-10 | 3 |
+ | 12 | 3 | 2023-12-10 | 4 |
+ | 13 | 4 | 2023-01-20 | 4 |
+ | 14 | 4 | 2023-04-20 | 4 |
+ | 15 | 4 | 2023-07-20 | 4 |
+ | 16 | 5 | 2023-02-15 | 3 |
+ | 17 | 5 | 2023-05-15 | 2 |
+ +-----------+-------------+-------------+--------+
+
+**Output:**
+
+ +-------------+----------------+-------------------+
+ | employee_id | name | improvement_score |
+ +-------------+----------------+-------------------+
+ | 2 | Bob Smith | 3 |
+ | 1 | Alice Johnson | 2 |
+ | 3 | Carol Davis | 2 |
+ +-------------+----------------+-------------------+
+
+**Explanation:**
+
+* **Alice Johnson (employee\_id = 1):**
+ * Has 4 reviews with ratings: 2, 3, 4, 5
+ * Last 3 reviews (by date): 2023-04-15 (3), 2023-07-15 (4), 2023-10-15 (5)
+ * Ratings are strictly increasing: 3 → 4 → 5
+ * Improvement score: 5 - 3 = 2
+* **Carol Davis (employee\_id = 3):**
+ * Has 4 reviews with ratings: 1, 2, 3, 4
+ * Last 3 reviews (by date): 2023-06-10 (2), 2023-09-10 (3), 2023-12-10 (4)
+ * Ratings are strictly increasing: 2 → 3 → 4
+ * Improvement score: 4 - 2 = 2
+* **Bob Smith (employee\_id = 2):**
+ * Has 4 reviews with ratings: 3, 2, 4, 5
+ * Last 3 reviews (by date): 2023-05-01 (2), 2023-08-01 (4), 2023-11-01 (5)
+ * Ratings are strictly increasing: 2 → 4 → 5
+ * Improvement score: 5 - 2 = 3
+* **Employees not included:**
+ * David Wilson (employee\_id = 4): Last 3 reviews are all 4 (no improvement)
+ * Emma Brown (employee\_id = 5): Only has 2 reviews (needs at least 3)
+
+The output table is ordered by improvement\_score in descending order, then by name in ascending order.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/script.sql b/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/script.sql
new file mode 100644
index 000000000..8596bd486
--- /dev/null
+++ b/src/main/java/g3501_3600/s3580_find_consistently_improving_employees/script.sql
@@ -0,0 +1,35 @@
+# Write your MySQL query statement below
+# #Medium #Database #2025_06_11_Time_449_ms_(91.67%)_Space_0.0_MB_(100.00%)
+WITH Ranked AS (
+ SELECT
+ e.employee_id,
+ e.name,
+ pr.review_date,
+ pr.rating,
+ RANK() OVER (
+ PARTITION BY e.employee_id
+ ORDER BY pr.review_date DESC
+ ) AS rnk,
+ LAG(pr.rating) OVER (
+ PARTITION BY e.employee_id
+ ORDER BY pr.review_date DESC
+ ) AS lag_rating
+ FROM employees e
+ LEFT JOIN performance_reviews pr
+ ON e.employee_id = pr.employee_id
+)
+SELECT
+ employee_id,
+ name,
+ MAX(rating) - MIN(rating) AS improvement_score
+FROM Ranked
+WHERE rnk <= 3
+GROUP BY
+ employee_id,
+ name
+HAVING
+ COUNT(*) = 3
+ AND SUM(CASE WHEN lag_rating > rating THEN 1 ELSE 0 END) = 2
+ORDER BY
+ improvement_score DESC,
+ name ASC;
diff --git a/src/test/java/com_github_leetcode/CommonUtils.java b/src/test/java/com_github_leetcode/CommonUtils.java
index 0705ee51e..551c5f036 100644
--- a/src/test/java/com_github_leetcode/CommonUtils.java
+++ b/src/test/java/com_github_leetcode/CommonUtils.java
@@ -6,20 +6,6 @@
public class CommonUtils {
- public static void printArray(int[] nums) {
- for (int i : nums) {
- System.out.print(i + ", ");
- }
- System.out.println();
- }
-
- public static void printArray(double[] nums) {
- for (double i : nums) {
- System.out.print(i + ", ");
- }
- System.out.println();
- }
-
public static boolean compareArray(int[] arr1, int[] arr2) {
for (int i : arr1) {
boolean include = false;
diff --git a/src/test/java/g0401_0500/s0478_generate_random_point_in_a_circle/SolutionTest.java b/src/test/java/g0401_0500/s0478_generate_random_point_in_a_circle/SolutionTest.java
index 0eab9f55d..9a7ec84a4 100644
--- a/src/test/java/g0401_0500/s0478_generate_random_point_in_a_circle/SolutionTest.java
+++ b/src/test/java/g0401_0500/s0478_generate_random_point_in_a_circle/SolutionTest.java
@@ -3,16 +3,15 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import com_github_leetcode.CommonUtils;
import org.junit.jupiter.api.Test;
class SolutionTest {
@Test
void randPoint() {
Solution solution = new Solution(1.0, 0.0, 0.0);
- CommonUtils.printArray(solution.randPoint());
- CommonUtils.printArray(solution.randPoint());
- CommonUtils.printArray(solution.randPoint());
+ solution.randPoint();
+ solution.randPoint();
+ solution.randPoint();
assertThat(solution, equalTo(solution));
}
}
diff --git a/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java b/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java
index bf75651df..71182eaf8 100644
--- a/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java
+++ b/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java
@@ -3,18 +3,17 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import com_github_leetcode.CommonUtils;
import org.junit.jupiter.api.Test;
class SolutionTest {
@Test
void solutionTest() {
Solution solution = new Solution(new int[][] {{-2, -2, 1, 1}, {2, 2, 4, 6}});
- CommonUtils.printArray(solution.pick());
- CommonUtils.printArray(solution.pick());
- CommonUtils.printArray(solution.pick());
- CommonUtils.printArray(solution.pick());
- CommonUtils.printArray(solution.pick());
+ solution.pick();
+ solution.pick();
+ solution.pick();
+ solution.pick();
+ solution.pick();
assertThat(true, equalTo(true));
}
}
diff --git a/src/test/java/g0501_0600/s0519_random_flip_matrix/SolutionTest.java b/src/test/java/g0501_0600/s0519_random_flip_matrix/SolutionTest.java
index 72162e695..9cb194b93 100644
--- a/src/test/java/g0501_0600/s0519_random_flip_matrix/SolutionTest.java
+++ b/src/test/java/g0501_0600/s0519_random_flip_matrix/SolutionTest.java
@@ -3,18 +3,17 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-import com_github_leetcode.CommonUtils;
import org.junit.jupiter.api.Test;
class SolutionTest {
@Test
void solutionTest() {
Solution solution = new Solution(3, 1);
- CommonUtils.printArray(solution.flip());
- CommonUtils.printArray(solution.flip());
- CommonUtils.printArray(solution.flip());
+ solution.flip();
+ solution.flip();
+ solution.flip();
solution.reset();
- CommonUtils.printArray(solution.flip());
+ solution.flip();
assertThat(true, equalTo(true));
}
}
diff --git a/src/test/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/SolutionTest.java b/src/test/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/SolutionTest.java
new file mode 100644
index 000000000..957a2f424
--- /dev/null
+++ b/src/test/java/g3501_3600/s3566_partition_array_into_two_equal_product_subsets/SolutionTest.java
@@ -0,0 +1,20 @@
+package g3501_3600.s3566_partition_array_into_two_equal_product_subsets;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void checkEqualPartitions() {
+ assertThat(
+ new Solution().checkEqualPartitions(new int[] {3, 1, 6, 8, 4}, 24L), equalTo(true));
+ }
+
+ @Test
+ void checkEqualPartitions2() {
+ assertThat(
+ new Solution().checkEqualPartitions(new int[] {2, 5, 3, 7}, 15L), equalTo(false));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/SolutionTest.java b/src/test/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/SolutionTest.java
new file mode 100644
index 000000000..08fdfbcce
--- /dev/null
+++ b/src/test/java/g3501_3600/s3567_minimum_absolute_difference_in_sliding_submatrix/SolutionTest.java
@@ -0,0 +1,28 @@
+package g3501_3600.s3567_minimum_absolute_difference_in_sliding_submatrix;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minAbsDiff() {
+ assertThat(
+ new Solution().minAbsDiff(new int[][] {{1, 8}, {3, -2}}, 2),
+ equalTo(new int[][] {{2}}));
+ }
+
+ @Test
+ void minAbsDiff2() {
+ assertThat(
+ new Solution().minAbsDiff(new int[][] {{3, -1}}, 1), equalTo(new int[][] {{0, 0}}));
+ }
+
+ @Test
+ void minAbsDiff3() {
+ assertThat(
+ new Solution().minAbsDiff(new int[][] {{1, -2, 3}, {2, 3, 5}}, 2),
+ equalTo(new int[][] {{1, 2}}));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/SolutionTest.java b/src/test/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/SolutionTest.java
new file mode 100644
index 000000000..42c1d9085
--- /dev/null
+++ b/src/test/java/g3501_3600/s3568_minimum_moves_to_clean_the_classroom/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3568_minimum_moves_to_clean_the_classroom;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minMoves() {
+ assertThat(new Solution().minMoves(new String[] {"S.", "XL"}, 2), equalTo(2));
+ }
+
+ @Test
+ void minMoves2() {
+ assertThat(new Solution().minMoves(new String[] {"LS", "RL"}, 4), equalTo(3));
+ }
+
+ @Test
+ void minMoves3() {
+ assertThat(new Solution().minMoves(new String[] {"L.S", "RXL"}, 3), equalTo(-1));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/SolutionTest.java b/src/test/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/SolutionTest.java
new file mode 100644
index 000000000..3f4a51693
--- /dev/null
+++ b/src/test/java/g3501_3600/s3569_maximize_count_of_distinct_primes_after_split/SolutionTest.java
@@ -0,0 +1,37 @@
+package g3501_3600.s3569_maximize_count_of_distinct_primes_after_split;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maximumCount() {
+ assertThat(
+ new Solution()
+ .maximumCount(new int[] {2, 1, 3, 1, 2}, new int[][] {{1, 2}, {3, 3}}),
+ equalTo(new int[] {3, 4}));
+ }
+
+ @Test
+ void maximumCount2() {
+ assertThat(
+ new Solution().maximumCount(new int[] {2, 1, 4}, new int[][] {{0, 1}}),
+ equalTo(new int[] {0}));
+ }
+
+ @Test
+ void maximumCount3() {
+ assertThat(
+ new Solution().maximumCount(new int[] {2, 34}, new int[][] {{1, 2}, {1, 3}}),
+ equalTo(new int[] {2, 2}));
+ }
+
+ @Test
+ void maximumCount4() {
+ assertThat(
+ new Solution().maximumCount(new int[] {4, 2}, new int[][] {{0, 2}, {0, 2}}),
+ equalTo(new int[] {2, 2}));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3570_find_books_with_no_available_copies/MysqlTest.java b/src/test/java/g3501_3600/s3570_find_books_with_no_available_copies/MysqlTest.java
new file mode 100644
index 000000000..4ae19d88e
--- /dev/null
+++ b/src/test/java/g3501_3600/s3570_find_books_with_no_available_copies/MysqlTest.java
@@ -0,0 +1,82 @@
+package g3501_3600.s3570_find_books_with_no_available_copies;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Collectors;
+import javax.sql.DataSource;
+import org.junit.jupiter.api.Test;
+import org.zapodot.junit.db.annotations.EmbeddedDatabase;
+import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
+import org.zapodot.junit.db.common.CompatibilityMode;
+
+@EmbeddedDatabaseTest(
+ compatibilityMode = CompatibilityMode.MySQL,
+ initialSqls =
+ "CREATE TABLE library_books(book_id INTEGER, title VARCHAR(255)"
+ + ", author VARCHAR(255), genre VARCHAR(255), publication_year "
+ + "INTEGER, total_copies INTEGER); "
+ + "INSERT INTO library_books (book_id, title, author, genre, "
+ + "publication_year, total_copies) VALUES "
+ + "(1, 'The Great Gatsby', 'F. Scott', 'Fiction', 1925, 3),"
+ + "(2, 'To Kill a Mockingbird', 'Harper Lee', 'Fiction', 1960, 3),"
+ + "(3, '1984', 'George Orwell', 'Dystopian', 1949, 1),"
+ + "(4, 'Pride and Prejudice', 'Jane Austen', 'Romance', 1813, 2),"
+ + "(5, 'The Catcher in the Rye','J.D. Salinger', 'Fiction', 1951, 1),"
+ + "(6, 'Brave New World', 'Aldous Huxley', 'Dystopian', 1932, 4);"
+ + "CREATE TABLE borrowing_records(record_id INTEGER, book_id INTEGER"
+ + ", borrower_name VARCHAR(255), borrow_date DATE, return_date DATE); "
+ + "INSERT INTO borrowing_records(record_id, book_id, borrower_name, "
+ + "borrow_date, return_date) VALUES "
+ + "(1, 1, 'Alice Smith', '2024-01-15', NULL),"
+ + "(2, 1, 'Bob Johnson', '2024-01-20', NULL),"
+ + "(3, 2, 'Carol White', '2024-01-10', '2024-01-25'),"
+ + "(4, 3, 'David Brown', '2024-02-01', NULL),"
+ + "(5, 4, 'Emma Wilson', '2024-01-05', NULL),"
+ + "(6, 5, 'Frank Davis', '2024-01-18', '2024-02-10'),"
+ + "(7, 1, 'Grace Miller', '2024-02-05', NULL),"
+ + "(8, 6, 'Henry Taylor', '2024-01-12', NULL),"
+ + "(9, 2, 'Ivan Clark', '2024-02-12', NULL),"
+ + "(10,2, 'Jane Adams', '2024-02-15', NULL);")
+class MysqlTest {
+ @Test
+ void testScript(@EmbeddedDatabase DataSource dataSource)
+ throws SQLException, FileNotFoundException {
+ try (final Connection connection = dataSource.getConnection()) {
+ try (final Statement statement = connection.createStatement();
+ final ResultSet resultSet =
+ statement.executeQuery(
+ new BufferedReader(
+ new FileReader(
+ "src/main/java/g3501_3600/"
+ + "s3570_find_books_with_no_available_copies/"
+ + "script.sql"))
+ .lines()
+ .collect(Collectors.joining("\n"))
+ .replaceAll("#.*?\\r?\\n", ""))) {
+ assertThat(resultSet.next(), equalTo(true));
+ assertThat(resultSet.getNString(1), equalTo("1"));
+ assertThat(resultSet.getNString(2), equalTo("The Great Gatsby"));
+ assertThat(resultSet.getNString(3), equalTo("F. Scott"));
+ assertThat(resultSet.getNString(4), equalTo("Fiction"));
+ assertThat(resultSet.getNString(5), equalTo("1925"));
+ assertThat(resultSet.getNString(6), equalTo("3"));
+ assertThat(resultSet.next(), equalTo(true));
+ assertThat(resultSet.getNString(1), equalTo("3"));
+ assertThat(resultSet.getNString(2), equalTo("1984"));
+ assertThat(resultSet.getNString(3), equalTo("George Orwell"));
+ assertThat(resultSet.getNString(4), equalTo("Dystopian"));
+ assertThat(resultSet.getNString(5), equalTo("1949"));
+ assertThat(resultSet.getNString(6), equalTo("1"));
+ assertThat(resultSet.next(), equalTo(false));
+ }
+ }
+ }
+}
diff --git a/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java b/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java
new file mode 100644
index 000000000..320f60a15
--- /dev/null
+++ b/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java
@@ -0,0 +1,25 @@
+package g3501_3600.s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxSumDistinctTriplet() {
+ assertThat(
+ new Solution()
+ .maxSumDistinctTriplet(
+ new int[] {1, 2, 1, 3, 2}, new int[] {5, 3, 4, 6, 2}),
+ equalTo(14));
+ }
+
+ @Test
+ void maxSumDistinctTriplet2() {
+ assertThat(
+ new Solution()
+ .maxSumDistinctTriplet(new int[] {1, 2, 1, 2}, new int[] {4, 5, 6, 7}),
+ equalTo(-1));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java b/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java
new file mode 100644
index 000000000..498f2e842
--- /dev/null
+++ b/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java
@@ -0,0 +1,20 @@
+package g3501_3600.s3573_best_time_to_buy_and_sell_stock_v;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maximumProfit() {
+ assertThat(new Solution().maximumProfit(new int[] {1, 7, 9, 8, 2}, 2), equalTo(14L));
+ }
+
+ @Test
+ void maximumProfit2() {
+ assertThat(
+ new Solution().maximumProfit(new int[] {12, 16, 19, 19, 8, 1, 19, 13, 9}, 3),
+ equalTo(36L));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java b/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java
new file mode 100644
index 000000000..f47b5578e
--- /dev/null
+++ b/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3574_maximize_subarray_gcd_score;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxGCDScore() {
+ assertThat(new Solution().maxGCDScore(new int[] {2, 4}, 1), equalTo(8L));
+ }
+
+ @Test
+ void maxGCDScore2() {
+ assertThat(new Solution().maxGCDScore(new int[] {3, 5, 7}, 2), equalTo(14L));
+ }
+
+ @Test
+ void maxGCDScore3() {
+ assertThat(new Solution().maxGCDScore(new int[] {5, 5, 5}, 1), equalTo(15L));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java b/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java
new file mode 100644
index 000000000..dce805cf9
--- /dev/null
+++ b/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java
@@ -0,0 +1,34 @@
+package g3501_3600.s3575_maximum_good_subtree_score;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void goodSubtreeSum() {
+ assertThat(new Solution().goodSubtreeSum(new int[] {2, 3}, new int[] {-1, 0}), equalTo(8));
+ }
+
+ @Test
+ void goodSubtreeSum2() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {1, 5, 2}, new int[] {-1, 0, 0}),
+ equalTo(15));
+ }
+
+ @Test
+ void goodSubtreeSum3() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {34, 1, 2}, new int[] {-1, 0, 1}),
+ equalTo(42));
+ }
+
+ @Test
+ void goodSubtreeSum4() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {3, 22, 5}, new int[] {-1, 0, 1}),
+ equalTo(18));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java b/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java
new file mode 100644
index 000000000..d0b864950
--- /dev/null
+++ b/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3576_transform_array_to_all_equal_elements;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void canMakeEqual() {
+ assertThat(new Solution().canMakeEqual(new int[] {1, -1, 1, -1, 1}, 3), equalTo(true));
+ }
+
+ @Test
+ void canMakeEqual2() {
+ assertThat(new Solution().canMakeEqual(new int[] {-1, -1, -1, 1, 1, 1}, 5), equalTo(false));
+ }
+
+ @Test
+ void canMakeEqual3() {
+ assertThat(new Solution().canMakeEqual(new int[] {1}, 3), equalTo(true));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java b/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java
new file mode 100644
index 000000000..ed457851f
--- /dev/null
+++ b/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3501_3600.s3577_count_the_number_of_computer_unlocking_permutations;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void countPermutations() {
+ assertThat(new Solution().countPermutations(new int[] {1, 2, 3}), equalTo(2));
+ }
+
+ @Test
+ void countPermutations2() {
+ assertThat(new Solution().countPermutations(new int[] {3, 3, 3, 4, 4, 4}), equalTo(0));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java b/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java
new file mode 100644
index 000000000..8e0c87733
--- /dev/null
+++ b/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3501_3600.s3578_count_partitions_with_max_min_difference_at_most_k;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void countPartitions() {
+ assertThat(new Solution().countPartitions(new int[] {9, 4, 1, 3, 7}, 4), equalTo(6));
+ }
+
+ @Test
+ void countPartitions2() {
+ assertThat(new Solution().countPartitions(new int[] {3, 3, 4}, 0), equalTo(2));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java b/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java
new file mode 100644
index 000000000..4c19c168d
--- /dev/null
+++ b/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3579_minimum_steps_to_convert_string_with_operations;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minOperations() {
+ assertThat(new Solution().minOperations("abcdf", "dacbe"), equalTo(4));
+ }
+
+ @Test
+ void minOperations2() {
+ assertThat(new Solution().minOperations("abceded", "baecfef"), equalTo(4));
+ }
+
+ @Test
+ void minOperations3() {
+ assertThat(new Solution().minOperations("abcdef", "fedabc"), equalTo(2));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3580_find_consistently_improving_employees/MysqlTest.java b/src/test/java/g3501_3600/s3580_find_consistently_improving_employees/MysqlTest.java
new file mode 100644
index 000000000..61f496ca0
--- /dev/null
+++ b/src/test/java/g3501_3600/s3580_find_consistently_improving_employees/MysqlTest.java
@@ -0,0 +1,82 @@
+package g3501_3600.s3580_find_consistently_improving_employees;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Collectors;
+import javax.sql.DataSource;
+import org.junit.jupiter.api.Test;
+import org.zapodot.junit.db.annotations.EmbeddedDatabase;
+import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
+import org.zapodot.junit.db.common.CompatibilityMode;
+
+@EmbeddedDatabaseTest(
+ compatibilityMode = CompatibilityMode.MySQL,
+ initialSqls =
+ "CREATE TABLE employees(employee_id INTEGER, name VARCHAR(255)); "
+ + "INSERT INTO employees (employee_id, name) VALUES"
+ + " (1, 'Alice Johnson'),"
+ + " (2, 'Bob Smith'),"
+ + " (3, 'Carol Davis'),"
+ + " (4, 'David Wilson'),"
+ + " (5, 'Emma Brown');"
+ + "CREATE TABLE performance_reviews(review_id INTEGER, employee_id INTEGER"
+ + ", review_date DATE, rating INTEGER); "
+ + "INSERT INTO performance_reviews (review_id, employee_id, review_date, rating) VALUES"
+ + " (1, 1, '2023-01-15', 2),"
+ + " (2, 1, '2023-04-15', 3),"
+ + " (3, 1, '2023-07-15', 4),"
+ + " (4, 1, '2023-10-15', 5),"
+ + " (5, 2, '2023-02-01', 3),"
+ + " (6, 2, '2023-05-01', 2),"
+ + " (7, 2, '2023-08-01', 4),"
+ + " (8, 2, '2023-11-01', 5),"
+ + " (9, 3, '2023-03-10', 1),"
+ + " (10, 3, '2023-06-10', 2),"
+ + " (11, 3, '2023-09-10', 3),"
+ + " (12, 3, '2023-12-10', 4),"
+ + " (13, 4, '2023-01-20', 4),"
+ + " (14, 4, '2023-04-20', 4),"
+ + " (15, 4, '2023-07-20', 4),"
+ + " (16, 5, '2023-02-15', 3),"
+ + " (17, 5, '2023-05-15', 2);")
+class MysqlTest {
+ @Test
+ void testScript(@EmbeddedDatabase DataSource dataSource)
+ throws SQLException, FileNotFoundException {
+ try (final Connection connection = dataSource.getConnection()) {
+ try (final Statement statement = connection.createStatement();
+ final ResultSet resultSet =
+ statement.executeQuery(
+ new BufferedReader(
+ new FileReader(
+ "src/main/java/g3501_3600/"
+ + "s3580_find_consistently_improving_employees/"
+ + "script.sql"))
+ .lines()
+ .collect(Collectors.joining("\n"))
+ .replaceAll("#.*?\\r?\\n", ""))) {
+ assertThat(resultSet.next(), equalTo(true));
+ assertThat(resultSet.getNString(1), equalTo("2"));
+ assertThat(resultSet.getNString(2), equalTo("Bob Smith"));
+ assertThat(resultSet.getNString(3), equalTo("3"));
+ assertThat(resultSet.next(), equalTo(true));
+ assertThat(resultSet.getNString(1), equalTo("1"));
+ assertThat(resultSet.getNString(2), equalTo("Alice Johnson"));
+ assertThat(resultSet.getNString(3), equalTo("2"));
+ assertThat(resultSet.next(), equalTo(true));
+ assertThat(resultSet.getNString(1), equalTo("3"));
+ assertThat(resultSet.getNString(2), equalTo("Carol Davis"));
+ assertThat(resultSet.getNString(3), equalTo("2"));
+ assertThat(resultSet.next(), equalTo(false));
+ }
+ }
+ }
+}