From 8bb17537707747d7a78ea5961350cbc814cf88b4 Mon Sep 17 00:00:00 2001 From: ThanhNIT Date: Fri, 8 May 2026 22:23:21 +0700 Subject: [PATCH 01/12] Added tasks 3760-3770 --- .../Solution.java | 22 ++ .../readme.md | 45 ++++ .../Solution.java | 26 ++ .../readme.md | 56 ++++ .../Solution.java | 255 ++++++++++++++++++ .../readme.md | 147 ++++++++++ .../s3764_most_common_course_pairs/readme.md | 91 +++++++ .../s3764_most_common_course_pairs/script.sql | 27 ++ .../s3765_complete_prime_number/Solution.java | 36 +++ .../s3765_complete_prime_number/readme.md | 53 ++++ .../Solution.java | 52 ++++ .../readme.md | 143 ++++++++++ .../Solution.java | 32 +++ .../readme.md | 58 ++++ .../Solution.java | 85 ++++++ .../readme.md | 56 ++++ .../Solution.java | 39 +++ .../readme.md | 50 ++++ .../Solution.java | 29 ++ .../readme.md | 40 +++ .../SolutionTest.java | 23 ++ .../SolutionTest.java | 23 ++ .../SolutionTest.java | 26 ++ .../MysqlTest.java | 94 +++++++ .../SolutionTest.java | 23 ++ .../SolutionTest.java | 31 +++ .../SolutionTest.java | 27 ++ .../SolutionTest.java | 23 ++ .../SolutionTest.java | 31 +++ .../SolutionTest.java | 23 ++ 30 files changed, 1666 insertions(+) create mode 100644 src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java create mode 100644 src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md create mode 100644 src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java create mode 100644 src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md create mode 100644 src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java create mode 100644 src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md create mode 100644 src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md create mode 100644 src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql create mode 100644 src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java create mode 100644 src/main/java/g3701_3800/s3765_complete_prime_number/readme.md create mode 100644 src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java create mode 100644 src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md create mode 100644 src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java create mode 100644 src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md create mode 100644 src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java create mode 100644 src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md create mode 100644 src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java create mode 100644 src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md create mode 100644 src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java create mode 100644 src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md create mode 100644 src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java create mode 100644 src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java create mode 100644 src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java diff --git a/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java new file mode 100644 index 000000000..2cf37828c --- /dev/null +++ b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java @@ -0,0 +1,22 @@ +package g3701_3800.s3760_maximum_substrings_with_distinct_start; + +// #Medium #String #Hash_Table #Senior #Weekly_Contest_478 +// #2026_05_08_Time_5_ms_(98.92%)_Space_47.79_MB_(74.99%) + +public class Solution { + public int maxDistinct(String s) { + int mask = 0; + int res = 0; + for (char c : s.toCharArray()) { + int bit = 1 << (c - 'a'); + if ((mask & bit) == 0) { + mask |= bit; + res++; + if (res == 26) { + break; + } + } + } + return res; + } +} diff --git a/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md new file mode 100644 index 000000000..d9243db58 --- /dev/null +++ b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md @@ -0,0 +1,45 @@ +3760\. Maximum Substrings With Distinct Start + +Medium + +You are given a string `s` consisting of lowercase English letters. + +Return an integer denoting the **maximum** number of substring you can split `s` into such that each **substring** starts with a **distinct** character (i.e., no two substrings start with the same character). + +**Example 1:** + +**Input:** s = "abab" + +**Output:** 2 + +**Explanation:** + +* Split `"abab"` into `"a"` and `"bab"`. +* Each substring starts with a distinct character i.e `'a'` and `'b'`. Thus, the answer is 2. + +**Example 2:** + +**Input:** s = "abcd" + +**Output:** 4 + +**Explanation:** + +* Split `"abcd"` into `"a"`, `"b"`, `"c"`, and `"d"`. +* Each substring starts with a distinct character. Thus, the answer is 4. + +**Example 3:** + +**Input:** s = "aaaa" + +**Output:** 1 + +**Explanation:** + +* All characters in `"aaaa"` are `'a'`. +* Only one substring can start with `'a'`. Thus, the answer is 1. + +**Constraints:** + +* 1 <= s.length <= 105 +* `s` consists of lowercase English letters. \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java new file mode 100644 index 000000000..96693e412 --- /dev/null +++ b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java @@ -0,0 +1,26 @@ +package g3701_3800.s3761_minimum_absolute_distance_between_mirror_pairs; + +// #Medium #Array #Hash_Table #Math #Staff #Weekly_Contest_478 +// #2026_05_08_Time_49_ms_(84.83%)_Space_95.13_MB_(49.31%) + +import java.util.HashMap; + +public class Solution { + public int minMirrorPairDistance(int[] nums) { + int res = 100000; + int i = 0; + HashMap seen = new HashMap<>(); + for (int n : nums) { + int r; + if (seen.containsKey(n)) { + res = Math.min(res, i - seen.get(n)); + } + for (r = 0; n > 0; n /= 10) { + r = r * 10 + (n % 10); + } + seen.put(r, i++); + } + + return res == 100000 ? -1 : res; + } +} diff --git a/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md new file mode 100644 index 000000000..7333c65d2 --- /dev/null +++ b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md @@ -0,0 +1,56 @@ +3761\. Minimum Absolute Distance Between Mirror Pairs + +Medium + +You are given an integer array `nums`. + +A **mirror pair** is a pair of indices `(i, j)` such that: + +* `0 <= i < j < nums.length`, and +* `reverse(nums[i]) == nums[j]`, where `reverse(x)` denotes the integer formed by reversing the digits of `x`. Leading zeros are omitted after reversing, for example `reverse(120) = 21`. + +Return the **minimum** absolute distance between the indices of any mirror pair. The absolute distance between indices `i` and `j` is `abs(i - j)`. + +If no mirror pair exists, return `-1`. + +**Example 1:** + +**Input:** nums = [12,21,45,33,54] + +**Output:** 1 + +**Explanation:** + +The mirror pairs are: + +* (0, 1) since `reverse(nums[0]) = reverse(12) = 21 = nums[1]`, giving an absolute distance `abs(0 - 1) = 1`. +* (2, 4) since `reverse(nums[2]) = reverse(45) = 54 = nums[4]`, giving an absolute distance `abs(2 - 4) = 2`. + +The minimum absolute distance among all pairs is 1. + +**Example 2:** + +**Input:** nums = [120,21] + +**Output:** 1 + +**Explanation:** + +There is only one mirror pair (0, 1) since `reverse(nums[0]) = reverse(120) = 21 = nums[1]`. + +The minimum absolute distance is 1. + +**Example 3:** + +**Input:** nums = [21,120] + +**Output:** \-1 + +**Explanation:** + +There are no mirror pairs in the array. + +**Constraints:** + +* 1 <= nums.length <= 105 +* 1 <= nums[i] <= 109 \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java new file mode 100644 index 000000000..125973b1f --- /dev/null +++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java @@ -0,0 +1,255 @@ +package g3701_3800.s3762_minimum_operations_to_equalize_subarrays; + +// #Hard #Array #Math #Binary_Search #Segment_Tree #Weekly_Contest_478 #Principal +// #2026_05_08_Time_540_ms_(100.00%)_Space_267.97_MB_(76.92%) + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public class Solution { + + static class MNode { + int l; + int r; + int[] vals; + long[] pref; + MNode left; + MNode right; + + MNode(int l, int r) { + this.l = l; + this.r = r; + } + } + + static class Group { + int[] pos; + int[] val; + long[] prefPos; + MNode root; + int minv; + int maxv; + } + + static int lowerBound(int[] a, int x) { + int l = 0; + int r = a.length; + while (l < r) { + int m = (l + r) >>> 1; + if (a[m] >= x) { + r = m; + } else { + l = m + 1; + } + } + return l; + } + + static int upperBound(int[] a, int x) { + int l = 0; + int r = a.length; + while (l < r) { + int m = (l + r) >>> 1; + if (a[m] > x) { + r = m; + } else { + l = m + 1; + } + } + return l; + } + + static MNode buildMerge(int[] arr, int l, int r) { + MNode node = new MNode(l, r); + if (l == r) { + node.vals = new int[] {arr[l]}; + node.pref = new long[] {arr[l]}; + return node; + } + int m = (l + r) >>> 1; + node.left = buildMerge(arr, l, m); + node.right = buildMerge(arr, m + 1, r); + int[] a = node.left.vals; + int[] b = node.right.vals; + int na = a.length; + int nb = b.length; + int[] c = new int[na + nb]; + long[] pref = new long[na + nb]; + int ia = 0; + int ib = 0; + int k = 0; + while (ia < na && ib < nb) { + if (a[ia] <= b[ib]) { + c[k++] = a[ia++]; + } else { + c[k++] = b[ib++]; + } + } + while (ia < na) { + c[k++] = a[ia++]; + } + while (ib < nb) { + c[k++] = b[ib++]; + } + pref[0] = c[0]; + for (int i = 1; i < c.length; i++) { + pref[i] = pref[i - 1] + c[i]; + } + node.vals = c; + node.pref = pref; + return node; + } + + static int countLE(MNode node, int ql, int qr, int x) { + if (node == null || ql > node.r || qr < node.l) { + return 0; + } + if (ql <= node.l && node.r <= qr) { + int idx = upperBound(node.vals, x) - 1; + return idx < 0 ? 0 : idx + 1; + } + return countLE(node.left, ql, qr, x) + countLE(node.right, ql, qr, x); + } + + static long sumLE(MNode node, int ql, int qr, int x) { + if (node == null || ql > node.r || qr < node.l) { + return 0L; + } + if (ql <= node.l && node.r <= qr) { + int idx = upperBound(node.vals, x) - 1; + return idx < 0 ? 0L : node.pref[idx]; + } + return sumLE(node.left, ql, qr, x) + sumLE(node.right, ql, qr, x); + } + + public long[] minOperations(int[] nums, int k, int[][] queries) { + Map groupHashMap = buildGroups(nums, k); + + long[] ans = new long[queries.length]; + + for (int qi = 0; qi < queries.length; qi++) { + ans[qi] = processQuery(nums, queries[qi], groupHashMap, k); + } + + return ans; + } + + private Map buildGroups(int[] nums, int k) { + Map> map = new HashMap<>(); + + for (int i = 0; i < nums.length; i++) { + int rem = nums[i] % k; + int value = nums[i] / k; + + map.computeIfAbsent(rem, z -> new ArrayList<>()).add(new int[] {i, value}); + } + + Map groupHashMap = new HashMap<>(); + + for (Map.Entry> entry : map.entrySet()) { + groupHashMap.put(entry.getKey(), createGroup(entry.getValue())); + } + + return groupHashMap; + } + + private Group createGroup(ArrayList arr) { + arr.sort(Comparator.comparingInt(a -> a[0])); + + int size = arr.size(); + + int[] pos = new int[size]; + int[] val = new int[size]; + long[] prefPos = new long[size]; + + int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; + + for (int i = 0; i < size; i++) { + pos[i] = arr.get(i)[0]; + val[i] = arr.get(i)[1]; + + min = Math.min(min, val[i]); + max = Math.max(max, val[i]); + + prefPos[i] = i == 0 ? val[i] : prefPos[i - 1] + val[i]; + } + + Group group = new Group(); + group.pos = pos; + group.val = val; + group.prefPos = prefPos; + group.minv = min; + group.maxv = max; + + if (size > 0) { + group.root = buildMerge(val, 0, size - 1); + } + + return group; + } + + private long processQuery(int[] nums, int[] query, Map groupHashMap, int k) { + int left = query[0]; + int right = query[1]; + + int rem = nums[left] % k; + + Group group = groupHashMap.get(rem); + + if (group == null) { + return -1; + } + + int l = lowerBound(group.pos, left); + int r = upperBound(group.pos, right) - 1; + + if (!isValidRange(left, right, l, r)) { + return -1; + } + + return calculateOperations(group, l, r); + } + + private boolean isValidRange(int left, int right, int l, int r) { + return l <= r && (r - l + 1 == right - left + 1); + } + + private long calculateOperations(Group group, int l, int r) { + int count = r - l + 1; + int median = findMedian(group, l, r, count); + + long leftCount = countLE(group.root, l, r, median); + long leftSum = sumLE(group.root, l, r, median); + + long total = group.prefPos[r] - (l == 0 ? 0L : group.prefPos[l - 1]); + + long rightSum = total - leftSum; + long rightCount = count - leftCount; + + return median * leftCount - leftSum + rightSum - median * rightCount; + } + + private int findMedian(Group group, int l, int r, int count) { + int need = (count + 1) / 2; + + int low = group.minv; + int high = group.maxv; + + while (low < high) { + int mid = low + ((high - low) >>> 1); + + int currentCount = countLE(group.root, l, r, mid); + + if (currentCount >= need) { + high = mid; + } else { + low = mid + 1; + } + } + + return low; + } +} diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md new file mode 100644 index 000000000..699f2003a --- /dev/null +++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md @@ -0,0 +1,147 @@ +3762\. Minimum Operations to Equalize Subarrays + +Hard + +You are given an integer array `nums` and an integer `k`. + +In one operation, you can **increase or decrease** any element of `nums` by **exactly** `k`. + +You are also given a 2D integer array `queries`, where each queries[i] = [li, ri]. + +For each query, find the **minimum** number of operations required to make **all** elements in the **non-empty subarrays** nums[li..ri] **equal**. If it is impossible, the answer for that query is `-1`. + +Return an array `ans`, where `ans[i]` is the answer for the ith query. + +**Example 1:** + +**Input:** nums = [1,4,7], k = 3, queries = [[0,1],[0,2]] + +**Output:** [1,2] + +**Explanation:** + +One optimal set of operations: + +`i` + +[li, ri] + +nums[li..ri] + +Possibility + +Operations + +Final +nums[li..ri] + +`ans[i]` + +0 + +[0, 1] + +[1, 4] + +Yes + +`nums[0] + k = 1 + 3 = 4 = nums[1]` + +[4, 4] + +1 + +1 + +[0, 2] + +[1, 4, 7] + +Yes + +`nums[0] + k = 1 + 3 = 4 = nums[1] +nums[2] - k = 7 - 3 = 4 = nums[1]` + +[4, 4, 4] + +2 + +Thus, `ans = [1, 2]`. + +**Example 2:** + +**Input:** nums = [1,2,4], k = 2, queries = [[0,2],[0,0],[1,2]] + +**Output:** [-1,0,1] + +**Explanation:** + +One optimal set of operations: + +`i` + +[li, ri] + +nums[li..ri] + +Possibility + +Operations + +Final +nums[li..ri] + +`ans[i]` + +0 + +[0, 2] + +[1, 2, 4] + +No + +\- + +[1, 2, 4] + +\-1 + +1 + +[0, 0] + +[1] + +Yes + +Already equal + +[1] + +0 + +2 + +[1, 2] + +[2, 4] + +Yes + +`nums[1] + k = 2 + 2 = 4 = nums[2]` + +[4, 4] + +1 + +Thus, `ans = [-1, 0, 1]`. + +**Constraints:** + +* 1 <= n == nums.length <= 4 × 104 +* 1 <= nums[i] <= 109 +* 1 <= k <= 109 +* 1 <= queries.length <= 4 × 104 +* queries[i] = [li, ri] +* 0 <= li <= ri <= n - 1 \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md new file mode 100644 index 000000000..a2b2f41cb --- /dev/null +++ b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md @@ -0,0 +1,91 @@ +3764\. Most Common Course Pairs + +Hard + +SQL Schema + +* * * + +Pandas Schema + +* * * + +Table: `course_completions` + ++-------------------+---------+ +| Column Name | Type | ++-------------------+---------+ +| user_id | int | +| course_id | int | +| course_name | varchar | +| completion_date | date | +| course_rating | int | ++-------------------+---------+ +(user_id, course_id) is the combination of columns with unique values for this table. Each row represents a completed course by a user with their rating (1-5 scale). + +Write a solution to identify **skill mastery pathways** by analyzing course completion sequences among top-performing students: + +* Consider only **top-performing students** (those who completed **at least** `5` **courses** with an **average rating of** `4` **or higher**). +* For each top performer, identify the **sequence of courses** they completed in chronological order. +* Find all **consecutive course pairs** (`Course A → Course B`) taken by these students. +* Return the **pair frequency**, identifying which course transitions are most common among high achievers. + +Return _the result table ordered by_ _pair frequency in **descending** order_ _and then by first course name and second course name in **ascending** order_. + +The result format is in the following example. + +**Example:** + +**Input:** + +course_completions table: + ++---------+-----------+---------------------+-----------------+---------------+ +| user_id | course_id | course_name | completion_date | course_rating | ++---------+-----------+---------------------+-----------------+---------------+ +| 1 | 101 | Python Basics | 2024-01-05 | 5 | +| 1 | 102 | SQL Fundamentals | 2024-02-10 | 4 | +| 1 | 103 | JavaScript | 2024-03-15 | 5 | +| 1 | 104 | React Basics | 2024-04-20 | 4 | +| 1 | 105 | Node.js | 2024-05-25 | 5 | +| 1 | 106 | Docker | 2024-06-30 | 4 | +| 2 | 101 | Python Basics | 2024-01-08 | 4 | +| 2 | 104 | React Basics | 2024-02-14 | 5 | +| 2 | 105 | Node.js | 2024-03-20 | 4 | +| 2 | 106 | Docker | 2024-04-25 | 5 | +| 2 | 107 | AWS Fundamentals | 2024-05-30 | 4 | +| 3 | 101 | Python Basics | 2024-01-10 | 3 | +| 3 | 102 | SQL Fundamentals | 2024-02-12 | 3 | +| 3 | 103 | JavaScript | 2024-03-18 | 3 | +| 3 | 104 | React Basics | 2024-04-22 | 2 | +| 3 | 105 | Node.js | 2024-05-28 | 3 | +| 4 | 101 | Python Basics | 2024-01-12 | 5 | +| 4 | 108 | Data Science | 2024-02-16 | 5 | +| 4 | 109 | Machine Learning | 2024-03-22 | 5 | ++---------+-----------+---------------------+-----------------+---------------+ + +**Output:** + ++------------------+-------------------+------------------+ +| first_course | second_course | transition_count | ++------------------+-------------------+------------------+ +| Node.js | Docker | 2 | +| React Basics | Node.js | 2 | +| Docker | AWS Fundamentals | 1 | +| JavaScript | React Basics | 1 | +| Python Basics | React Basics | 1 | +| Python Basics | SQL Fundamentals | 1 | +| SQL Fundamentals | JavaScript | 1 | ++------------------+-------------------+------------------+ +**Explanation:** + +* **User 1**: Completed 6 courses with average rating 4.5 (qualifies as top performer) +* **User 2**: Completed 5 courses with average rating 4.4 (qualifies as top performer) +* **User 3**: Completed 5 courses but average rating is 2.8 (does not qualify) +* **User 4**: Completed only 3 courses (does not qualify) +* **Course Pairs Among Top Performers**: + * User 1: Python Basics → SQL Fundamentals → JavaScript → React Basics → Node.js → Docker + * User 2: Python Basics → React Basics → Node.js → Docker → AWS Fundamentals + * Most common transitions: Node.js → Docker (2 times), React Basics → Node.js (2 times) + +Results are ordered by transition_count in descending order, then by first_course in ascending order, and then by second_course in ascending order. \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql b/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql new file mode 100644 index 000000000..4ea151824 --- /dev/null +++ b/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql @@ -0,0 +1,27 @@ +# Write your MySQL query statement below +# #Hard #2026_05_08_Time_262_ms_(63.61%)_Space_0.0_MB_(100.00%) +-- Find the most common course-to-next-course transitions +-- among engaged users (>=5 courses, avg rating >= 4) +SELECT + course_name AS first_course, + next_course AS second_course, + COUNT(*) AS transition_count +FROM ( + SELECT + *, + LEAD(course_name) OVER ( + PARTITION BY user_id + ORDER BY completion_date + ) AS next_course + FROM course_completions + WHERE user_id IN ( + SELECT user_id + FROM course_completions + GROUP BY user_id + HAVING COUNT(course_id) >= 5 + AND AVG(course_rating) >= 4 + ) +) AS t +WHERE next_course IS NOT NULL +GROUP BY course_name, next_course +ORDER BY transition_count DESC, first_course ASC, second_course ASC; diff --git a/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java b/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java new file mode 100644 index 000000000..e00537b2d --- /dev/null +++ b/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java @@ -0,0 +1,36 @@ +package g3701_3800.s3765_complete_prime_number; + +// #Medium #Math #Enumeration #Number_Theory #Senior #Biweekly_Contest_171 +// #2026_05_08_Time_2_ms_(91.62%)_Space_42.93_MB_(55.39%) + +public class Solution { + private boolean isPrime(int n) { + if (n != 2 && n % 2 == 0) { + return false; + } + for (int i = 3; i * i <= n; i += 2) { + if (n % i == 0) { + return false; + } + } + return true; + } + + public boolean completePrime(int num) { + int y = 0; + int z = 1; + int x = num; + while (x > 0) { + y = z * (x % 10) + y; + if (y == 1 || !isPrime(y)) { + return false; + } + if (x == 1 || !isPrime(x)) { + return false; + } + x /= 10; + z *= 10; + } + return true; + } +} diff --git a/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md b/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md new file mode 100644 index 000000000..36922bd1f --- /dev/null +++ b/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md @@ -0,0 +1,53 @@ +3765\. Complete Prime Number + +Medium + +You are given an integer `num`. + +A number `num` is called a **Complete Prime Number** if every **prefix** and every **suffix** of `num` is **prime**. + +Return `true` if `num` is a Complete Prime Number, otherwise return `false`. + +**Note**: + +* A **prefix** of a number is formed by the **first** `k` digits of the number. +* A **suffix** of a number is formed by the **last** `k` digits of the number. +* Single-digit numbers are considered Complete Prime Numbers only if they are **prime**. + +**Example 1:** + +**Input:** num = 23 + +**Output:** true + +**Explanation:** + +* Prefixes of `num = 23` are 2 and 23, both are prime. +* Suffixes of `num = 23` are 3 and 23, both are prime. +* All prefixes and suffixes are prime, so 23 is a Complete Prime Number and the answer is `true`. + +**Example 2:** + +**Input:** num = 39 + +**Output:** false + +**Explanation:** + +* Prefixes of `num = 39` are 3 and 39. 3 is prime, but 39 is not prime. +* Suffixes of `num = 39` are 9 and 39. Both 9 and 39 are not prime. +* At least one prefix or suffix is not prime, so 39 is not a Complete Prime Number and the answer is `false`. + +**Example 3:** + +**Input:** num = 7 + +**Output:** true + +**Explanation:** + +* 7 is prime, so all its prefixes and suffixes are prime and the answer is `true`. + +**Constraints:** + +* 1 <= num <= 109 \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java new file mode 100644 index 000000000..cbc5a7a17 --- /dev/null +++ b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java @@ -0,0 +1,52 @@ +package g3701_3800.s3766_minimum_operations_to_make_binary_palindrome; + +// #Medium #Array #Binary_Search #Two_Pointers #Bit_Manipulation #Staff #Biweekly_Contest_171 +// #2026_05_08_Time_54_ms_(82.69%)_Space_47.43_MB_(64.42%) + +public class Solution { + private int binlen(int n) { + int c = 0; + while (n > 0) { + c++; + n >>= 1; + } + return c; + } + + private boolean isPal(int n) { + int l = 0; + int r = binlen(n) - 1; + while (l < r) { + if (((n >> l) & 1) != ((n >> r) & 1)) { + return false; + } + l++; + r--; + } + return true; + } + + public int[] minOperations(int[] nums) { + boolean[] binary = new boolean[5050]; + int[] ans = new int[nums.length]; + for (int i = 0; i < 5050; i++) { + binary[i] = isPal(i); + } + for (int i = 0; i < nums.length; i++) { + int a = nums[i]; + int b = nums[i]; + int c1 = 0; + int c2 = 0; + while (!binary[a]) { + a--; + c1++; + } + while (!binary[b]) { + b++; + c2++; + } + ans[i] = Math.min(c1, c2); + } + return ans; + } +} diff --git a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md new file mode 100644 index 000000000..8cbb1008b --- /dev/null +++ b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md @@ -0,0 +1,143 @@ +3766\. Minimum Operations to Make Binary Palindrome + +Medium + +You are given an integer array `nums`. + +For each element `nums[i]`, you may perform the following operations **any** number of times (including zero): + +* Increase `nums[i]` by 1, or +* Decrease `nums[i]` by 1. + +A number is called a **binary palindrome** if its binary representation without leading zeros reads the same forward and backward. + +Your task is to return an integer array `ans`, where `ans[i]` represents the **minimum** number of operations required to convert `nums[i]` into a **binary palindrome**. + +**Example 1:** + +**Input:** nums = [1,2,4] + +**Output:** [0,1,1] + +**Explanation:** + +One optimal set of operations: + +`nums[i]` + +Binary(`nums[i]`) + +Nearest +Palindrome + +Binary +(Palindrome) + +Operations Required + +`ans[i]` + +1 + +1 + +1 + +1 + +Already palindrome + +0 + +2 + +10 + +3 + +11 + +Increase by 1 + +1 + +4 + +100 + +3 + +11 + +Decrease by 1 + +1 + +Thus, `ans = [0, 1, 1]`. + +**Example 2:** + +**Input:** nums = [6,7,12] + +**Output:** [1,0,3] + +**Explanation:** + +One optimal set of operations: + +`nums[i]` + +Binary(`nums[i]`) + +Nearest +Palindrome + +Binary +(Palindrome) + +Operations Required + +`ans[i]` + +6 + +110 + +5 + +101 + +Decrease by 1 + +1 + +7 + +111 + +7 + +111 + +Already palindrome + +0 + +12 + +1100 + +15 + +1111 + +Increase by 3 + +3 + +Thus, `ans = [1, 0, 3]`. + +**Constraints:** + +* `1 <= nums.length <= 5000` +* `1 <= nums[i] <= 5000` \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java new file mode 100644 index 000000000..f3160e34b --- /dev/null +++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java @@ -0,0 +1,32 @@ +package g3701_3800.s3767_maximize_points_after_choosing_k_tasks; + +// #Medium #Array #Sorting #Greedy #Heap_Priority_Queue #Staff #Biweekly_Contest_171 +// #2026_05_08_Time_96_ms_(61.94%)_Space_136.84_MB_(77.61%) + +import java.util.Arrays; + +public class Solution { + public long maxPoints(int[] technique1, int[] technique2, int k) { + int n = technique1.length; + Integer[] idx = new Integer[n]; + for (int i = 0; i < n; i++) { + idx[i] = i; + } + + // Sort by (technique1[i] - technique2[i]) descending + Arrays.sort( + idx, (a, b) -> (technique1[b] - technique2[b]) - (technique1[a] - technique2[a])); + + long ans = 0; + for (int i = 0; i < k; i++) { + ans += technique1[idx[i]]; + } + + // Remaining choose best from both + for (int i = k; i < n; i++) { + ans += Math.max(technique1[idx[i]], technique2[idx[i]]); + } + + return ans; + } +} diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md new file mode 100644 index 000000000..d61da8f1e --- /dev/null +++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md @@ -0,0 +1,58 @@ +3767\. Maximize Points After Choosing K Tasks + +Medium + +You are given two integer arrays, `technique1` and `technique2`, each of length `n`, where `n` represents the number of tasks to complete. + +* If the ith task is completed using technique 1, you earn `technique1[i]` points. +* If it is completed using technique 2, you earn `technique2[i]` points. + +You are also given an integer `k`, representing the **minimum** number of tasks that **must** be completed using technique 1. + +You **must** complete **at least** `k` tasks using technique 1 (they do not need to be the first `k` tasks). + +The remaining tasks may be completed using **either** technique. + +Return an integer denoting the **maximum total points** you can earn. + +**Example 1:** + +**Input:** technique1 = [5,2,10], technique2 = [10,3,8], k = 2 + +**Output:** 22 + +**Explanation:** + +We must complete at least `k = 2` tasks using `technique1`. + +Choosing `technique1[1]` and `technique1[2]` (completed using technique 1), and `technique2[0]` (completed using technique 2), yields the maximum points: `2 + 10 + 10 = 22`. + +**Example 2:** + +**Input:** technique1 = [10,20,30], technique2 = [5,15,25], k = 2 + +**Output:** 60 + +**Explanation:** + +We must complete at least `k = 2` tasks using `technique1`. + +Choosing all tasks using technique 1 yields the maximum points: `10 + 20 + 30 = 60`. + +**Example 3:** + +**Input:** technique1 = [1,2,3], technique2 = [4,5,6], k = 0 + +**Output:** 15 + +**Explanation:** + +Since `k = 0`, we are not required to choose any task using `technique1`. + +Choosing all tasks using technique 2 yields the maximum points: `4 + 5 + 6 = 15`. + +**Constraints:** + +* 1 <= n == technique1.length == technique2.length <= 105 +* 1 <= technique1[i], technique2[i] <= 105 +* `0 <= k <= n` \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java new file mode 100644 index 000000000..183ecbdee --- /dev/null +++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java @@ -0,0 +1,85 @@ +package g3701_3800.s3768_minimum_inversion_count_in_subarrays_of_fixed_length; + +// #Hard #Array #Sliding_Window #Segment_Tree #Senior_Staff #Biweekly_Contest_171 +// #2026_05_08_Time_181_ms_(75.47%)_Space_199.94_MB_(13.21%) + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class Solution { + public long minInversionCount(int[] nums, int k) { + int n = nums.length; + + int[] s = nums.clone(); + Arrays.sort(s); + Map rank = new HashMap<>(); + int r = 1; + for (int x : s) { + if (!rank.containsKey(x)) { + rank.put(x, r++); + } + } + + int[] c = new int[n]; + for (int i = 0; i < n; i++) { + c[i] = rank.get(nums[i]); + } + + int mv = r + 1; + Tree t = new Tree(mv); + + long inv = 0; + for (int i = 0; i < k; i++) { + inv += t.getQuery(c[i] + 1, mv); + t.update(c[i], 1); + } + + long mininv = inv; + + for (int i = k; i < n; i++) { + t.update(c[i - k], -1); + inv -= t.getQuery(1, c[i - k] - 1); + + inv += t.getQuery(c[i] + 1, mv); + t.update(c[i], 1); + + mininv = Math.min(mininv, inv); + } + + return mininv; + } + + static class Tree { + int[] t; + int n; + + Tree(int size) { + n = size; + t = new int[n + 2]; + } + + void update(int i, int v) { + while (i < t.length) { + t[i] += v; + i += i & -i; + } + } + + int query(int i) { + int res = 0; + while (i > 0) { + res += t[i]; + i -= i & -i; + } + return res; + } + + int getQuery(int l, int r) { + if (l > r) { + return 0; + } + return query(r) - query(l - 1); + } + } +} diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md new file mode 100644 index 000000000..7088d2594 --- /dev/null +++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md @@ -0,0 +1,56 @@ +3768\. Minimum Inversion Count in Subarrays of Fixed Length + +Hard + +You are given an integer array `nums` of length `n` and an integer `k`. + +An **inversion** is a pair of indices `(i, j)` from `nums` such that `i < j` and `nums[i] > nums[j]`. + +The **inversion count** of a **non-empty subarrays** is the number of inversions within it. + +Return the **minimum** inversion count among all **subarrays** of `nums` with length `k`. + +**Example 1:** + +**Input:** nums = [3,1,2,5,4], k = 3 + +**Output:** 0 + +**Explanation:** + +We consider all subarrays of length `k = 3` (indices below are relative to each subarray): + +* `[3, 1, 2]` has 2 inversions: `(0, 1)` and `(0, 2)`. +* `[1, 2, 5]` has 0 inversions. +* `[2, 5, 4]` has 1 inversion: `(1, 2)`. + +The minimum inversion count among all subarrays of length `3` is 0, achieved by subarray `[1, 2, 5]`. + +**Example 2:** + +**Input:** nums = [5,3,2,1], k = 4 + +**Output:** 6 + +**Explanation:** + +There is only one subarray of length `k = 4`: `[5, 3, 2, 1]`. +Within this subarray, the inversions are: `(0, 1)`, `(0, 2)`, `(0, 3)`, `(1, 2)`, `(1, 3)`, and `(2, 3)`. +Total inversions is 6, so the minimum inversion count is 6. + +**Example 3:** + +**Input:** nums = [2,1], k = 1 + +**Output:** 0 + +**Explanation:** + +All subarrays of length `k = 1` contain only one element, so no inversions are possible. +The minimum inversion count is therefore 0. + +**Constraints:** + +* 1 <= n == nums.length <= 105 +* 1 <= nums[i] <= 109 +* `1 <= k <= n` \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java new file mode 100644 index 000000000..af1994d26 --- /dev/null +++ b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java @@ -0,0 +1,39 @@ +package g3701_3800.s3769_sort_integers_by_binary_reflection; + +// #Easy #Array #Sorting #Mid_Level #Weekly_Contest_479 +// #2026_05_08_Time_5_ms_(97.23%)_Space_46.52_MB_(97.70%) + +import java.util.PriorityQueue; + +public class Solution { + public int[] sortByReflection(int[] nums) { + PriorityQueue minHeap = + new PriorityQueue<>( + (a, b) -> { + if (a[1] == b[1]) { + return Integer.compare(a[0], b[0]); + } + return Integer.compare(a[1], b[1]); + }); + int[] sortedByReflection = new int[nums.length]; + for (int num : nums) { + minHeap.offer(new int[] {num, reverseBinary(num)}); + } + int idx = 0; + while (!minHeap.isEmpty()) { + sortedByReflection[idx++] = minHeap.poll()[0]; + } + + return sortedByReflection; + } + + private int reverseBinary(int num) { + int reversed = 0; + while (num > 0) { + int lastBit = num & 1; + reversed = (reversed << 1) | lastBit; + num = num >> 1; + } + return reversed; + } +} diff --git a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md new file mode 100644 index 000000000..b93acafb7 --- /dev/null +++ b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md @@ -0,0 +1,50 @@ +3769\. Sort Integers by Binary Reflection + +Easy + +You are given an integer array `nums`. + +The **binary reflection** of a **positive** integer is defined as the number obtained by reversing the order of its **binary** digits (ignoring any leading zeros) and interpreting the resulting binary number as a decimal. + +Sort the array in **ascending** order based on the binary reflection of each element. If two different numbers have the same binary reflection, the **smaller** original number should appear first. + +Return the resulting sorted array. + +**Example 1:** + +**Input:** nums = [4,5,4] + +**Output:** [4,4,5] + +**Explanation:** + +Binary reflections are: + +* 4 -> (binary) `100` -> (reversed) `001` -> 1 +* 5 -> (binary) `101` -> (reversed) `101` -> 5 +* 4 -> (binary) `100` -> (reversed) `001` -> 1 + +Sorting by the reflected values gives `[4, 4, 5]`. + +**Example 2:** + +**Input:** nums = [3,6,5,8] + +**Output:** [8,3,6,5] + +**Explanation:** + +Binary reflections are: + +* 3 -> (binary) `11` -> (reversed) `11` -> 3 +* 6 -> (binary) `110` -> (reversed) `011` -> 3 +* 5 -> (binary) `101` -> (reversed) `101` -> 5 +* 8 -> (binary) `1000` -> (reversed) `0001` -> 1 + +Sorting by the reflected values gives `[8, 3, 6, 5]`. +Note that 3 and 6 have the same reflection, so we arrange them in increasing order of original value. + +**Constraints:** + +* `1 <= nums.length <= 100` +* 1 <= nums[i] <= 109 \ No newline at end of file diff --git a/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java new file mode 100644 index 000000000..d14e8e197 --- /dev/null +++ b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java @@ -0,0 +1,29 @@ +package g3701_3800.s3770_largest_prime_from_consecutive_prime_sum; + +// #Medium #Array #Math #Number_Theory #Senior #Weekly_Contest_479 +// #2026_05_08_Time_1_ms_(100.00%)_Space_42.47_MB_(96.28%) + +public class Solution { + static int[] ppr = { + 2, 5, 17, 41, 197, 281, 7699, 8893, 22039, 24133, 25237, 28697, 32353, 37561, 38921, 43201, + 44683, 55837, 61027, 66463, 70241, 86453, 102001, 109147, 116533, 119069, 121631, 129419, + 132059, 263171, 287137, 325019, 329401, 333821, 338279, 342761, 360979, 379667, 393961, + 398771 + }; + + public int largestPrime(int n) { + int i = 0; + int j = ppr.length - 1; + int r = 0; + while (i <= j) { + int m = (i + j) >> 1; + if (ppr[m] <= n) { + r = ppr[m]; + i = m + 1; + } else { + j = m - 1; + } + } + return r; + } +} diff --git a/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md new file mode 100644 index 000000000..303111e34 --- /dev/null +++ b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md @@ -0,0 +1,40 @@ +3770\. Largest Prime from Consecutive Prime Sum + +Medium + +You are given an integer `n`. + +Return the **largest prime number** less than or equal to `n` that can be expressed as the **sum** of one or more **consecutive prime numbers** starting from 2. If no such number exists, return 0. + +**Example 1:** + +**Input:** n = 20 + +**Output:** 17 + +**Explanation:** + +The prime numbers less than or equal to `n = 20` which are consecutive prime sums are: + +* `2 = 2` + +* `5 = 2 + 3` + +* `17 = 2 + 3 + 5 + 7` + + +The largest is 17, so it is the answer. + +**Example 2:** + +**Input:** n = 2 + +**Output:** 2 + +**Explanation:** + +The only consecutive prime sum less than or equal to 2 is 2 itself. + +**Constraints:** + +* 1 <= n <= 5 * 105 \ No newline at end of file diff --git a/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java b/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java new file mode 100644 index 000000000..a2a375ff3 --- /dev/null +++ b/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java @@ -0,0 +1,23 @@ +package g3701_3800.s3760_maximum_substrings_with_distinct_start; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxDistinct() { + assertThat(new Solution().maxDistinct("abca"), equalTo(3)); + } + + @Test + void maxDistinct2() { + assertThat(new Solution().maxDistinct("aaaa"), equalTo(1)); + } + + @Test + void maxDistinct3() { + assertThat(new Solution().maxDistinct("abcdefghijklmnopqrstuvwxyz"), equalTo(26)); + } +} diff --git a/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java b/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java new file mode 100644 index 000000000..e052f0d18 --- /dev/null +++ b/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java @@ -0,0 +1,23 @@ +package g3701_3800.s3761_minimum_absolute_distance_between_mirror_pairs; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minMirrorPairDistance() { + assertThat(new Solution().minMirrorPairDistance(new int[] {12, 21}), equalTo(1)); + } + + @Test + void minMirrorPairDistance2() { + assertThat(new Solution().minMirrorPairDistance(new int[] {10, 1, 100}), equalTo(1)); + } + + @Test + void minMirrorPairDistance3() { + assertThat(new Solution().minMirrorPairDistance(new int[] {12, 34, 56}), equalTo(-1)); + } +} diff --git a/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java b/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java new file mode 100644 index 000000000..bd3eaa460 --- /dev/null +++ b/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java @@ -0,0 +1,26 @@ +package g3701_3800.s3762_minimum_operations_to_equalize_subarrays; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minOperations() { + long[] result = new Solution().minOperations(new int[] {1, 3, 5}, 2, new int[][] {{0, 2}}); + assertThat(result[0], equalTo(2L)); + } + + @Test + void minOperations2() { + long[] result = new Solution().minOperations(new int[] {1, 3, 5}, 2, new int[][] {{0, 1}}); + assertThat(result[0], equalTo(1L)); + } + + @Test + void minOperations3() { + long[] result = new Solution().minOperations(new int[] {1, 2}, 2, new int[][] {{0, 1}}); + assertThat(result[0], equalTo(-1L)); + } +} diff --git a/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java b/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java new file mode 100644 index 000000000..874284821 --- /dev/null +++ b/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java @@ -0,0 +1,94 @@ +package g3701_3800.s3764_most_common_course_pairs; + +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.ArrayList; +import java.util.Arrays; +import java.util.List; +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 course_completions (" + + " user_id INTEGER," + + " course_id INTEGER," + + " course_name VARCHAR(512)," + + " completion_date DATE," + + " course_rating INTEGER," + + " PRIMARY KEY (user_id, course_id)" + + ");" + + "INSERT INTO course_completions (user_id, course_id, course_name, completion_date," + + " course_rating) VALUES" + + "(1, 101, 'Python Basics', '2024-01-05', 5)," + + "(1, 102, 'SQL Fundamentals', '2024-02-10', 4)," + + "(1, 103, 'JavaScript', '2024-03-15', 5)," + + "(1, 104, 'React Basics', '2024-04-20', 4)," + + "(1, 105, 'Node.js', '2024-05-25', 5)," + + "(1, 106, 'Docker', '2024-06-30', 4)," + + "(2, 101, 'Python Basics', '2024-01-08', 4)," + + "(2, 104, 'React Basics', '2024-02-14', 5)," + + "(2, 105, 'Node.js', '2024-03-20', 4)," + + "(2, 106, 'Docker', '2024-04-25', 5)," + + "(2, 107, 'AWS Fundamentals', '2024-05-30', 4)," + + "(3, 101, 'Python Basics', '2024-01-10', 3)," + + "(3, 102, 'SQL Fundamentals', '2024-02-12', 3)," + + "(3, 103, 'JavaScript', '2024-03-18', 3)," + + "(3, 104, 'React Basics', '2024-04-22', 2)," + + "(3, 105, 'Node.js', '2024-05-28', 3)," + + "(4, 101, 'Python Basics', '2024-01-12', 5)," + + "(4, 108, 'Data Science', '2024-02-16', 5)," + + "(4, 109, 'Machine Learning', '2024-03-22', 5);") +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/g3701_3800/" + + "s3764_most_common_course_pairs/" + + "script.sql")) + .lines() + .collect(Collectors.joining("\n")) + .replaceAll("#.*?\\r?\\n", ""))) { + List actualRows = new ArrayList<>(); + while (resultSet.next()) { + actualRows.add( + resultSet.getString(1) + + "|" + + resultSet.getString(2) + + "|" + + resultSet.getString(3)); + } + + List expectedRows = + Arrays.asList( + "Node.js|Docker|2", + "React Basics|Node.js|2", + "Docker|AWS Fundamentals|1", + "JavaScript|React Basics|1", + "Python Basics|React Basics|1", + "Python Basics|SQL Fundamentals|1", + "SQL Fundamentals|JavaScript|1"); + assertThat(actualRows, equalTo(expectedRows)); + } + } + } +} diff --git a/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java b/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java new file mode 100644 index 000000000..b1e3478a0 --- /dev/null +++ b/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java @@ -0,0 +1,23 @@ +package g3701_3800.s3765_complete_prime_number; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void completePrime() { + assertThat(new Solution().completePrime(239), equalTo(false)); + } + + @Test + void completePrime2() { + assertThat(new Solution().completePrime(21), equalTo(false)); + } + + @Test + void completePrime3() { + assertThat(new Solution().completePrime(2), equalTo(true)); + } +} diff --git a/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java b/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java new file mode 100644 index 000000000..e0113c123 --- /dev/null +++ b/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java @@ -0,0 +1,31 @@ +package g3701_3800.s3766_minimum_operations_to_make_binary_palindrome; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minOperations() { + int[] result = new Solution().minOperations(new int[] {5, 6, 7}); + assertThat(result[0], equalTo(0)); + assertThat(result[1], equalTo(1)); + assertThat(result[2], equalTo(0)); + } + + @Test + void minOperations2() { + int[] result = new Solution().minOperations(new int[] {10}); + assertThat(result[0], equalTo(1)); + } + + @Test + void minOperations3() { + int[] result = new Solution().minOperations(new int[] {1, 2, 3, 4}); + assertThat(result[0], equalTo(0)); + assertThat(result[1], equalTo(1)); + assertThat(result[2], equalTo(0)); + assertThat(result[3], equalTo(1)); + } +} diff --git a/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java new file mode 100644 index 000000000..e5200402b --- /dev/null +++ b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java @@ -0,0 +1,27 @@ +package g3701_3800.s3767_maximize_points_after_choosing_k_tasks; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxPoints() { + assertThat( + new Solution().maxPoints(new int[] {5, 1, 3}, new int[] {4, 10, 2}, 1), + equalTo(18L)); + } + + @Test + void maxPoints2() { + assertThat(new Solution().maxPoints(new int[] {1, 2}, new int[] {3, 4}, 0), equalTo(7L)); + } + + @Test + void maxPoints3() { + assertThat( + new Solution().maxPoints(new int[] {7, 2, 5}, new int[] {1, 8, 4}, 3), + equalTo(14L)); + } +} diff --git a/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java b/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java new file mode 100644 index 000000000..60ca5c1e0 --- /dev/null +++ b/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java @@ -0,0 +1,23 @@ +package g3701_3800.s3768_minimum_inversion_count_in_subarrays_of_fixed_length; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minInversionCount() { + assertThat(new Solution().minInversionCount(new int[] {3, 1, 2}, 2), equalTo(0L)); + } + + @Test + void minInversionCount2() { + assertThat(new Solution().minInversionCount(new int[] {3, 2, 1}, 3), equalTo(3L)); + } + + @Test + void minInversionCount3() { + assertThat(new Solution().minInversionCount(new int[] {1, 2, 3, 4}, 2), equalTo(0L)); + } +} diff --git a/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java b/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java new file mode 100644 index 000000000..88d8e9ac5 --- /dev/null +++ b/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java @@ -0,0 +1,31 @@ +package g3701_3800.s3769_sort_integers_by_binary_reflection; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void sortByReflection() { + int[] result = new Solution().sortByReflection(new int[] {1, 2, 3}); + assertThat(result[0], equalTo(1)); + assertThat(result[1], equalTo(2)); + assertThat(result[2], equalTo(3)); + } + + @Test + void sortByReflection2() { + int[] result = new Solution().sortByReflection(new int[] {0, 1, 2}); + assertThat(result[0], equalTo(0)); + assertThat(result[1], equalTo(1)); + assertThat(result[2], equalTo(2)); + } + + @Test + void sortByReflection3() { + int[] result = new Solution().sortByReflection(new int[] {6, 9}); + assertThat(result[0], equalTo(6)); + assertThat(result[1], equalTo(9)); + } +} diff --git a/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java b/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java new file mode 100644 index 000000000..be82bfa3a --- /dev/null +++ b/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java @@ -0,0 +1,23 @@ +package g3701_3800.s3770_largest_prime_from_consecutive_prime_sum; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void largestPrime() { + assertThat(new Solution().largestPrime(100), equalTo(41)); + } + + @Test + void largestPrime2() { + assertThat(new Solution().largestPrime(2), equalTo(2)); + } + + @Test + void largestPrime3() { + assertThat(new Solution().largestPrime(1), equalTo(0)); + } +} From d25d79a59d82ec8428492e09b6fd1b573aaaa2c7 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 19:37:02 +0300 Subject: [PATCH 02/12] Revise readme for course completions schema details --- .../s3764_most_common_course_pairs/readme.md | 99 +++++++++---------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md index a2b2f41cb..492a1b7d6 100644 --- a/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md +++ b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md @@ -2,26 +2,19 @@ Hard -SQL Schema - -* * * - -Pandas Schema - -* * * - Table: `course_completions` -+-------------------+---------+ -| Column Name | Type | -+-------------------+---------+ -| user_id | int | -| course_id | int | -| course_name | varchar | -| completion_date | date | -| course_rating | int | -+-------------------+---------+ -(user_id, course_id) is the combination of columns with unique values for this table. Each row represents a completed course by a user with their rating (1-5 scale). + +-------------------+---------+ + | Column Name | Type | + +-------------------+---------+ + | user_id | int | + | course_id | int | + | course_name | varchar | + | completion_date | date | + | course_rating | int | + +-------------------+---------+ + (user_id, course_id) is the combination of columns with unique values for this table. + Each row represents a completed course by a user with their rating (1-5 scale). Write a solution to identify **skill mastery pathways** by analyzing course completion sequences among top-performing students: @@ -40,43 +33,43 @@ The result format is in the following example. course_completions table: -+---------+-----------+---------------------+-----------------+---------------+ -| user_id | course_id | course_name | completion_date | course_rating | -+---------+-----------+---------------------+-----------------+---------------+ -| 1 | 101 | Python Basics | 2024-01-05 | 5 | -| 1 | 102 | SQL Fundamentals | 2024-02-10 | 4 | -| 1 | 103 | JavaScript | 2024-03-15 | 5 | -| 1 | 104 | React Basics | 2024-04-20 | 4 | -| 1 | 105 | Node.js | 2024-05-25 | 5 | -| 1 | 106 | Docker | 2024-06-30 | 4 | -| 2 | 101 | Python Basics | 2024-01-08 | 4 | -| 2 | 104 | React Basics | 2024-02-14 | 5 | -| 2 | 105 | Node.js | 2024-03-20 | 4 | -| 2 | 106 | Docker | 2024-04-25 | 5 | -| 2 | 107 | AWS Fundamentals | 2024-05-30 | 4 | -| 3 | 101 | Python Basics | 2024-01-10 | 3 | -| 3 | 102 | SQL Fundamentals | 2024-02-12 | 3 | -| 3 | 103 | JavaScript | 2024-03-18 | 3 | -| 3 | 104 | React Basics | 2024-04-22 | 2 | -| 3 | 105 | Node.js | 2024-05-28 | 3 | -| 4 | 101 | Python Basics | 2024-01-12 | 5 | -| 4 | 108 | Data Science | 2024-02-16 | 5 | -| 4 | 109 | Machine Learning | 2024-03-22 | 5 | -+---------+-----------+---------------------+-----------------+---------------+ + +---------+-----------+---------------------+-----------------+---------------+ + | user_id | course_id | course_name | completion_date | course_rating | + +---------+-----------+---------------------+-----------------+---------------+ + | 1 | 101 | Python Basics | 2024-01-05 | 5 | + | 1 | 102 | SQL Fundamentals | 2024-02-10 | 4 | + | 1 | 103 | JavaScript | 2024-03-15 | 5 | + | 1 | 104 | React Basics | 2024-04-20 | 4 | + | 1 | 105 | Node.js | 2024-05-25 | 5 | + | 1 | 106 | Docker | 2024-06-30 | 4 | + | 2 | 101 | Python Basics | 2024-01-08 | 4 | + | 2 | 104 | React Basics | 2024-02-14 | 5 | + | 2 | 105 | Node.js | 2024-03-20 | 4 | + | 2 | 106 | Docker | 2024-04-25 | 5 | + | 2 | 107 | AWS Fundamentals | 2024-05-30 | 4 | + | 3 | 101 | Python Basics | 2024-01-10 | 3 | + | 3 | 102 | SQL Fundamentals | 2024-02-12 | 3 | + | 3 | 103 | JavaScript | 2024-03-18 | 3 | + | 3 | 104 | React Basics | 2024-04-22 | 2 | + | 3 | 105 | Node.js | 2024-05-28 | 3 | + | 4 | 101 | Python Basics | 2024-01-12 | 5 | + | 4 | 108 | Data Science | 2024-02-16 | 5 | + | 4 | 109 | Machine Learning | 2024-03-22 | 5 | + +---------+-----------+---------------------+-----------------+---------------+ **Output:** -+------------------+-------------------+------------------+ -| first_course | second_course | transition_count | -+------------------+-------------------+------------------+ -| Node.js | Docker | 2 | -| React Basics | Node.js | 2 | -| Docker | AWS Fundamentals | 1 | -| JavaScript | React Basics | 1 | -| Python Basics | React Basics | 1 | -| Python Basics | SQL Fundamentals | 1 | -| SQL Fundamentals | JavaScript | 1 | -+------------------+-------------------+------------------+ + +------------------+-------------------+------------------+ + | first_course | second_course | transition_count | + +------------------+-------------------+------------------+ + | Node.js | Docker | 2 | + | React Basics | Node.js | 2 | + | Docker | AWS Fundamentals | 1 | + | JavaScript | React Basics | 1 | + | Python Basics | React Basics | 1 | + | Python Basics | SQL Fundamentals | 1 | + | SQL Fundamentals | JavaScript | 1 | + +------------------+-------------------+------------------+ **Explanation:** * **User 1**: Completed 6 courses with average rating 4.5 (qualifies as top performer) @@ -88,4 +81,4 @@ course_completions table: * User 2: Python Basics → React Basics → Node.js → Docker → AWS Fundamentals * Most common transitions: Node.js → Docker (2 times), React Basics → Node.js (2 times) -Results are ordered by transition_count in descending order, then by first_course in ascending order, and then by second_course in ascending order. \ No newline at end of file +Results are ordered by transition_count in descending order, then by first_course in ascending order, and then by second_course in ascending order. From 35e65bbfadf50e3c1ca2e65464cb5b150b2d19f7 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 19:43:24 +0300 Subject: [PATCH 03/12] Enhance readme with examples and explanations --- .../readme.md | 110 ++---------------- 1 file changed, 10 insertions(+), 100 deletions(-) diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md index 699f2003a..f0f048abe 100644 --- a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md +++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md @@ -22,49 +22,10 @@ Return an array `ans`, where `ans[i]` is the answer for the ith One optimal set of operations: -`i` - -[li, ri] - -nums[li..ri] - -Possibility - -Operations - -Final -nums[li..ri] - -`ans[i]` - -0 - -[0, 1] - -[1, 4] - -Yes - -`nums[0] + k = 1 + 3 = 4 = nums[1]` - -[4, 4] - -1 - -1 - -[0, 2] - -[1, 4, 7] - -Yes - -`nums[0] + k = 1 + 3 = 4 = nums[1] -nums[2] - k = 7 - 3 = 4 = nums[1]` - -[4, 4, 4] - -2 +| `i` | `[l_i, r_i]` | `nums[l_i..r_i]` | Possibility | Operations | Final `nums[l_i..r_i]` | `ans[i]` | +|---|---|---|---|---|---|---| +| 0 | [0, 1] | [1, 4] | Yes | `nums[0] + k = 1 + 3 = 4 = nums[1]` | [4, 4] | 1 | +| 1 | [0, 2] | [1, 4, 7] | Yes | `nums[0] + k = 1 + 3 = 4 = nums[1]`
`nums[2] - k = 7 - 3 = 4 = nums[1]` | [4, 4, 4] | 2 | Thus, `ans = [1, 2]`. @@ -78,62 +39,11 @@ Thus, `ans = [1, 2]`. One optimal set of operations: -`i` - -[li, ri] - -nums[li..ri] - -Possibility - -Operations - -Final -nums[li..ri] - -`ans[i]` - -0 - -[0, 2] - -[1, 2, 4] - -No - -\- - -[1, 2, 4] - -\-1 - -1 - -[0, 0] - -[1] - -Yes - -Already equal - -[1] - -0 - -2 - -[1, 2] - -[2, 4] - -Yes - -`nums[1] + k = 2 + 2 = 4 = nums[2]` - -[4, 4] - -1 +| `i` | `[l_i, r_i]` | `nums[l_i..r_i]` | Possibility | Operations | Final `nums[l_i..r_i]` | `ans[i]` | +|---|---|---|---|---|---|---| +| 0 | [0, 2] | [1, 2, 4] | No | - | [1, 2, 4] | -1 | +| 1 | [0, 0] | [1] | Yes | Already equal | [1] | 0 | +| 2 | [1, 2] | [2, 4] | Yes | `nums[1] + k = 2 + 2 = 4 = nums[2]` | [4, 4] | 1 | Thus, `ans = [-1, 0, 1]`. @@ -144,4 +54,4 @@ Thus, `ans = [-1, 0, 1]`. * 1 <= k <= 109 * 1 <= queries.length <= 4 × 104 * queries[i] = [li, ri] -* 0 <= li <= ri <= n - 1 \ No newline at end of file +* 0 <= li <= ri <= n - 1 From af2912b651bc39f89c126883572be6f8287fa70e Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 19:50:30 +0300 Subject: [PATCH 04/12] Change static to private for inner classes and methods --- .../Solution.java | 49 +++---------------- 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java index 125973b1f..f95f68fc3 100644 --- a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java +++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java @@ -1,7 +1,7 @@ package g3701_3800.s3762_minimum_operations_to_equalize_subarrays; // #Hard #Array #Math #Binary_Search #Segment_Tree #Weekly_Contest_478 #Principal -// #2026_05_08_Time_540_ms_(100.00%)_Space_267.97_MB_(76.92%) +// #2026_05_08_Time_528_ms_(100.00%)_Space_267.97_MB_(76.92%) import java.util.ArrayList; import java.util.Comparator; @@ -9,8 +9,7 @@ import java.util.Map; public class Solution { - - static class MNode { + private static class MNode { int l; int r; int[] vals; @@ -24,7 +23,7 @@ static class MNode { } } - static class Group { + private static class Group { int[] pos; int[] val; long[] prefPos; @@ -33,7 +32,7 @@ static class Group { int maxv; } - static int lowerBound(int[] a, int x) { + private static int lowerBound(int[] a, int x) { int l = 0; int r = a.length; while (l < r) { @@ -47,7 +46,7 @@ static int lowerBound(int[] a, int x) { return l; } - static int upperBound(int[] a, int x) { + private int upperBound(int[] a, int x) { int l = 0; int r = a.length; while (l < r) { @@ -61,7 +60,7 @@ static int upperBound(int[] a, int x) { return l; } - static MNode buildMerge(int[] arr, int l, int r) { + private MNode buildMerge(int[] arr, int l, int r) { MNode node = new MNode(l, r); if (l == r) { node.vals = new int[] {arr[l]}; @@ -102,7 +101,7 @@ static MNode buildMerge(int[] arr, int l, int r) { return node; } - static int countLE(MNode node, int ql, int qr, int x) { + private int countLE(MNode node, int ql, int qr, int x) { if (node == null || ql > node.r || qr < node.l) { return 0; } @@ -113,7 +112,7 @@ static int countLE(MNode node, int ql, int qr, int x) { return countLE(node.left, ql, qr, x) + countLE(node.right, ql, qr, x); } - static long sumLE(MNode node, int ql, int qr, int x) { + private long sumLE(MNode node, int ql, int qr, int x) { if (node == null || ql > node.r || qr < node.l) { return 0L; } @@ -126,90 +125,67 @@ static long sumLE(MNode node, int ql, int qr, int x) { public long[] minOperations(int[] nums, int k, int[][] queries) { Map groupHashMap = buildGroups(nums, k); - long[] ans = new long[queries.length]; - for (int qi = 0; qi < queries.length; qi++) { ans[qi] = processQuery(nums, queries[qi], groupHashMap, k); } - return ans; } private Map buildGroups(int[] nums, int k) { Map> map = new HashMap<>(); - for (int i = 0; i < nums.length; i++) { int rem = nums[i] % k; int value = nums[i] / k; - map.computeIfAbsent(rem, z -> new ArrayList<>()).add(new int[] {i, value}); } - Map groupHashMap = new HashMap<>(); - for (Map.Entry> entry : map.entrySet()) { groupHashMap.put(entry.getKey(), createGroup(entry.getValue())); } - return groupHashMap; } private Group createGroup(ArrayList arr) { arr.sort(Comparator.comparingInt(a -> a[0])); - int size = arr.size(); - int[] pos = new int[size]; int[] val = new int[size]; long[] prefPos = new long[size]; - int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; - for (int i = 0; i < size; i++) { pos[i] = arr.get(i)[0]; val[i] = arr.get(i)[1]; - min = Math.min(min, val[i]); max = Math.max(max, val[i]); - prefPos[i] = i == 0 ? val[i] : prefPos[i - 1] + val[i]; } - Group group = new Group(); group.pos = pos; group.val = val; group.prefPos = prefPos; group.minv = min; group.maxv = max; - if (size > 0) { group.root = buildMerge(val, 0, size - 1); } - return group; } private long processQuery(int[] nums, int[] query, Map groupHashMap, int k) { int left = query[0]; int right = query[1]; - int rem = nums[left] % k; - Group group = groupHashMap.get(rem); - if (group == null) { return -1; } - int l = lowerBound(group.pos, left); int r = upperBound(group.pos, right) - 1; - if (!isValidRange(left, right, l, r)) { return -1; } - return calculateOperations(group, l, r); } @@ -220,36 +196,27 @@ private boolean isValidRange(int left, int right, int l, int r) { private long calculateOperations(Group group, int l, int r) { int count = r - l + 1; int median = findMedian(group, l, r, count); - long leftCount = countLE(group.root, l, r, median); long leftSum = sumLE(group.root, l, r, median); - long total = group.prefPos[r] - (l == 0 ? 0L : group.prefPos[l - 1]); - long rightSum = total - leftSum; long rightCount = count - leftCount; - return median * leftCount - leftSum + rightSum - median * rightCount; } private int findMedian(Group group, int l, int r, int count) { int need = (count + 1) / 2; - int low = group.minv; int high = group.maxv; - while (low < high) { int mid = low + ((high - low) >>> 1); - int currentCount = countLE(group.root, l, r, mid); - if (currentCount >= need) { high = mid; } else { low = mid + 1; } } - return low; } } From 1e79106c0aa1f400cf277abd7fab704f39e540ee Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 19:53:20 +0300 Subject: [PATCH 05/12] Refactor readme for clarity and formatting --- .../readme.md | 110 ++---------------- 1 file changed, 11 insertions(+), 99 deletions(-) diff --git a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md index 8cbb1008b..1eb6ac57a 100644 --- a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md +++ b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md @@ -23,55 +23,11 @@ Your task is to return an integer array `ans`, where `ans[i]` represents the **m One optimal set of operations: -`nums[i]` - -Binary(`nums[i]`) - -Nearest -Palindrome - -Binary -(Palindrome) - -Operations Required - -`ans[i]` - -1 - -1 - -1 - -1 - -Already palindrome - -0 - -2 - -10 - -3 - -11 - -Increase by 1 - -1 - -4 - -100 - -3 - -11 - -Decrease by 1 - -1 +| `nums[i]` | Binary(`nums[i]`) | Nearest Palindrome | Binary (Palindrome) | Operations Required | `ans[i]` | +|---|---|---|---|---|---| +| 1 | 1 | 1 | 1 | Already palindrome | 0 | +| 2 | 10 | 3 | 11 | Increase by 1 | 1 | +| 4 | 100 | 3 | 11 | Decrease by 1 | 1 | Thus, `ans = [0, 1, 1]`. @@ -85,59 +41,15 @@ Thus, `ans = [0, 1, 1]`. One optimal set of operations: -`nums[i]` - -Binary(`nums[i]`) - -Nearest -Palindrome - -Binary -(Palindrome) - -Operations Required - -`ans[i]` - -6 - -110 - -5 - -101 - -Decrease by 1 - -1 - -7 - -111 - -7 - -111 - -Already palindrome - -0 - -12 - -1100 - -15 - -1111 - -Increase by 3 - -3 +| `nums[i]` | Binary(`nums[i]`) | Nearest Palindrome | Binary (Palindrome) | Operations Required | `ans[i]` | +|---|---|---|---|---|---| +| 6 | 110 | 5 | 101 | Decrease by 1 | 1 | +| 7 | 111 | 7 | 111 | Already palindrome | 0 | +| 12 | 1100 | 15 | 1111 | Increase by 3 | 3 | Thus, `ans = [1, 0, 3]`. **Constraints:** * `1 <= nums.length <= 5000` -* `1 <= nums[i] <= 5000` \ No newline at end of file +* `1 <= nums[i] <= 5000` From 4e4f56f0fc122559636a63bc6be2556718871b00 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 19:57:04 +0300 Subject: [PATCH 06/12] Refactor maxPoints method for efficiency --- .../Solution.java | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java index f3160e34b..c3a922a6d 100644 --- a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java +++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java @@ -1,32 +1,30 @@ package g3701_3800.s3767_maximize_points_after_choosing_k_tasks; // #Medium #Array #Sorting #Greedy #Heap_Priority_Queue #Staff #Biweekly_Contest_171 -// #2026_05_08_Time_96_ms_(61.94%)_Space_136.84_MB_(77.61%) +// #2026_05_08_Time_21_ms_(100.00%)_Space_130.40_MB_(85.82%) -import java.util.Arrays; +import java.util.PriorityQueue; public class Solution { public long maxPoints(int[] technique1, int[] technique2, int k) { int n = technique1.length; - Integer[] idx = new Integer[n]; - for (int i = 0; i < n; i++) { - idx[i] = i; - } - - // Sort by (technique1[i] - technique2[i]) descending - Arrays.sort( - idx, (a, b) -> (technique1[b] - technique2[b]) - (technique1[a] - technique2[a])); - + int use2 = n - k; + PriorityQueue min = new PriorityQueue(); long ans = 0; - for (int i = 0; i < k; i++) { - ans += technique1[idx[i]]; + for (int i = 0; i < n; ++i) { + int diff = technique2[i] - technique1[i]; + if (diff > 0) { + if (min.size() < use2) { + min.offer(diff); + ans += diff; + } else if (!min.isEmpty() && min.peek() < diff) { + ans -= min.poll(); + min.offer(diff); + ans += diff; + } + } + ans += technique1[i]; } - - // Remaining choose best from both - for (int i = k; i < n; i++) { - ans += Math.max(technique1[idx[i]], technique2[idx[i]]); - } - return ans; } } From 3cf397b79aea76de9eaf7e3edf9f17a3a3c8f5ec Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:04:59 +0300 Subject: [PATCH 07/12] Refactor inversion count logic and remove unused code --- .../Solution.java | 91 +++++++------------ 1 file changed, 33 insertions(+), 58 deletions(-) diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java index 183ecbdee..53c493a94 100644 --- a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java +++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java @@ -1,85 +1,60 @@ package g3701_3800.s3768_minimum_inversion_count_in_subarrays_of_fixed_length; // #Hard #Array #Sliding_Window #Segment_Tree #Senior_Staff #Biweekly_Contest_171 -// #2026_05_08_Time_181_ms_(75.47%)_Space_199.94_MB_(13.21%) +// #2026_05_08_Time_157_ms_(94.34%)_Space_125.70_MB_(100.00%) import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; public class Solution { public long minInversionCount(int[] nums, int k) { int n = nums.length; - - int[] s = nums.clone(); - Arrays.sort(s); - Map rank = new HashMap<>(); - int r = 1; - for (int x : s) { - if (!rank.containsKey(x)) { - rank.put(x, r++); - } - } - - int[] c = new int[n]; + // discretization of coordinates + int[] sorted = nums.clone(); + Arrays.sort(sorted); for (int i = 0; i < n; i++) { - c[i] = rank.get(nums[i]); + nums[i] = Arrays.binarySearch(sorted, nums[i]) + 1; } - - int mv = r + 1; - Tree t = new Tree(mv); - - long inv = 0; - for (int i = 0; i < k; i++) { - inv += t.getQuery(c[i] + 1, mv); - t.update(c[i], 1); - } - - long mininv = inv; - - for (int i = k; i < n; i++) { - t.update(c[i - k], -1); - inv -= t.getQuery(1, c[i - k] - 1); - - inv += t.getQuery(c[i] + 1, mv); - t.update(c[i], 1); - - mininv = Math.min(mininv, inv); + BinaryIndexedTree bit = new BinaryIndexedTree(n); + long invCount = 0L; + long ans = Long.MAX_VALUE; + for (int i = 0; i < n; i++) { + bit.add(nums[i], 1); + invCount += Math.min(i + 1, k) - bit.presum(nums[i]); + if (i < k - 1) { + continue; + } + ans = Math.min(ans, invCount); + invCount -= bit.presum(nums[i - k + 1] - 1); + bit.add(nums[i - k + 1], -1); } - - return mininv; + return ans; } - static class Tree { - int[] t; - int n; + private class BinaryIndexedTree { + private final int[] tree; - Tree(int size) { - n = size; - t = new int[n + 2]; + public BinaryIndexedTree(int n) { + tree = new int[n + 1]; } - void update(int i, int v) { - while (i < t.length) { - t[i] += v; - i += i & -i; + public void add(int i, int val) { + while (i < tree.length) { + tree[i] += val; + i += lowbit(i); } } - int query(int i) { - int res = 0; + public int presum(int i) { + int sum = 0; while (i > 0) { - res += t[i]; - i -= i & -i; + sum += tree[i]; + i -= lowbit(i); } - return res; + return sum; } - int getQuery(int l, int r) { - if (l > r) { - return 0; - } - return query(r) - query(l - 1); + private int lowbit(int n) { + return n & (-n); } } } From 6cc89813a030ddc910da9841829ed642d6ed8550 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:06:24 +0300 Subject: [PATCH 08/12] Fix priority queue initialization in Solution.java --- .../s3767_maximize_points_after_choosing_k_tasks/Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java index c3a922a6d..c8f52ac0a 100644 --- a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java +++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java @@ -9,7 +9,7 @@ public class Solution { public long maxPoints(int[] technique1, int[] technique2, int k) { int n = technique1.length; int use2 = n - k; - PriorityQueue min = new PriorityQueue(); + PriorityQueue min = new PriorityQueue<>(); long ans = 0; for (int i = 0; i < n; ++i) { int diff = technique2[i] - technique1[i]; From c9aaa9b041823ed5ac104e708b70d24bccc59197 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:07:25 +0300 Subject: [PATCH 09/12] Fix formatting issue in Solution.java --- .../s3769_sort_integers_by_binary_reflection/Solution.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java index af1994d26..b7b3832a9 100644 --- a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java +++ b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java @@ -23,7 +23,6 @@ public int[] sortByReflection(int[] nums) { while (!minHeap.isEmpty()) { sortedByReflection[idx++] = minHeap.poll()[0]; } - return sortedByReflection; } From b7cd1f2f594ea1914c1a86ff7a9df06e8e707112 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:14:27 +0300 Subject: [PATCH 10/12] Add additional test cases for maxPoints method --- .../SolutionTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java index e5200402b..fe39fda45 100644 --- a/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java +++ b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java @@ -24,4 +24,39 @@ void maxPoints3() { new Solution().maxPoints(new int[] {7, 2, 5}, new int[] {1, 8, 4}, 3), equalTo(14L)); } + + @Test + void maxPoints4() { + assertThat( + new Solution().maxPoints(new int[] {5, 4, 3}, new int[] {3, 4, 1}, 3), + equalTo(12L)); + } + + @Test + void maxPoints5() { + assertThat( + new Solution().maxPoints(new int[] {1, 2, 3}, new int[] {5, 5, 1}, 1), + equalTo(13L)); + } + + @Test + void maxPoints6() { + assertThat( + new Solution().maxPoints(new int[] {1, 1, 1, 1}, new int[] {3, 4, 2, 6}, 2), + equalTo(12L)); + } + + @Test + void maxPoints7() { + assertThat( + new Solution().maxPoints(new int[] {1, 1, 1, 1}, new int[] {6, 5, 4, 0}, 2), + equalTo(13L)); + } + + @Test + void maxPoints8() { + assertThat( + new Solution().maxPoints(new int[] {7, 8, 9}, new int[] {100, 100, 100}, 3), + equalTo(24L)); + } } From 8adce38cc0096b6ddfb08369db432bed8c846feb Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:16:25 +0300 Subject: [PATCH 11/12] Fix formatting issues in Solution.java --- .../Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java index 53c493a94..9c082812b 100644 --- a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java +++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java @@ -21,7 +21,7 @@ public long minInversionCount(int[] nums, int k) { bit.add(nums[i], 1); invCount += Math.min(i + 1, k) - bit.presum(nums[i]); if (i < k - 1) { - continue; + continue; } ans = Math.min(ans, invCount); invCount -= bit.presum(nums[i - k + 1] - 1); From 1bf9d11c9b714714d56b9bee7bd13cf14f85dcba Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 8 May 2026 20:19:30 +0300 Subject: [PATCH 12/12] Fix formatting issues in Solution.java --- .../Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java index 9c082812b..a48cdb007 100644 --- a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java +++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java @@ -21,7 +21,7 @@ public long minInversionCount(int[] nums, int k) { bit.add(nums[i], 1); invCount += Math.min(i + 1, k) - bit.presum(nums[i]); if (i < k - 1) { - continue; + continue; } ans = Math.min(ans, invCount); invCount -= bit.presum(nums[i - k + 1] - 1);