diff --git a/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/Solution.java b/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/Solution.java new file mode 100644 index 000000000..f75038a93 --- /dev/null +++ b/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/Solution.java @@ -0,0 +1,143 @@ +package g3801_3900.s3841_palindromic_path_queries_in_a_tree; + +// #Hard #Array #String #Tree #Bit_Manipulation #Divide_and_Conquer #Segment_Tree +// #Biweekly_Contest_176 #Principal #Depth_First_Search +// #2026_07_22_Time_65_ms_(100.00%)_Space_185.61_MB_(96.67%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Solution { + private int[] head; + private int[] to; + private int[] next; + + private int[][] lift; + private int[] first; + private int[] last; + private int[] depth; + private int time = 0; + private int maxPower; + + public List palindromePath(int n, int[][] edges, String s, String[] queries) { + this.first = new int[n]; + this.last = new int[n]; + this.maxPower = 31 - Integer.numberOfLeadingZeros(n); + this.depth = new int[n]; + this.lift = new int[maxPower + 1][n]; + int m = edges.length; + this.head = new int[n]; + this.to = new int[m << 1]; + this.next = new int[m << 1]; + Arrays.fill(head, -1); + for (int i = 0; i < m; i++) { + int a = edges[i][0]; + int b = edges[i][1]; + to[i << 1] = b; + next[i << 1] = head[a]; + head[a] = i << 1; + to[i << 1 | 1] = a; + next[i << 1 | 1] = head[b]; + head[b] = i << 1 | 1; + } + dfs(0, -1); + BIT bit = new BIT(n + 1); + char[] arr = s.toCharArray(); + for (int i = 0; i < n; i++) { + bit.update(first[i], 1 << arr[i] - 'a'); + bit.update(last[i] + 1, 1 << arr[i] - 'a'); + } + ArrayList list = new ArrayList<>(queries.length); + for (String query : queries) { + if (query.charAt(0) == 'u') { + int i = Integer.parseInt(query.substring(7, query.length() - 2)); + char c = query.charAt(query.length() - 1); + if (c == arr[i]) { + continue; + } + int filter = 1 << arr[i] - 'a' | 1 << c - 'a'; + bit.update(first[i], filter); + arr[i] = c; + bit.update(last[i] + 1, filter); + } else { + int i1 = query.indexOf(' '); + int i2 = query.lastIndexOf(' '); + int a = Integer.parseInt(query.substring(i1 + 1, i2)); + int b = Integer.parseInt(query.substring(i2 + 1)); + int r = bit.query(first[a]) ^ bit.query(first[b]) ^ 1 << arr[lca(a, b)] - 'a'; + list.add((r & r - 1) == 0); + } + } + return list; + } + + private int lca(int a, int b) { + if (depth[a] > depth[b]) { + int temp = a; + a = b; + b = temp; + } + if (first[a] <= first[b] && last[a] >= last[b]) { + return a; + } + int diff = depth[b] - depth[a]; + for (int i = maxPower; diff != 0; --i) { + if (diff >= 1 << i) { + b = lift[i][b]; + diff -= 1 << i; + } + } + if (a == b) { + return a; + } + for (int i = maxPower; i >= 0; --i) { + if (lift[i][a] != lift[i][b]) { + a = lift[i][a]; + b = lift[i][b]; + } + } + return lift[0][a]; + } + + private void dfs(int index, int prev) { + first[index] = ++time; + for (int x = head[index]; x != -1; x = next[x]) { + int nextIndex = to[x]; + if (nextIndex == prev) { + continue; + } + depth[nextIndex] = depth[index] + 1; + lift[0][nextIndex] = index; + for (int i = 1; (1 << i) < depth[nextIndex]; i++) { + lift[i][nextIndex] = lift[i - 1][lift[i - 1][nextIndex]]; + } + dfs(nextIndex, index); + } + last[index] = time; + } + + private static class BIT { + private final int[] ints; + private final int n; + + BIT(int n) { + this.n = n; + this.ints = new int[n + 1]; + } + + public void update(int index, int val) { + for (int i = index + 1; i <= n; i += i & -i) { + ints[i] ^= val; + } + } + + public int query(int index) { + int ans = 0; + for (int i = index + 1; i > 0; i -= i & -i) { + ans ^= ints[i]; + } + return ans; + } + } +} diff --git a/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/readme.md b/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/readme.md new file mode 100644 index 000000000..c3a4b229c --- /dev/null +++ b/src/main/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/readme.md @@ -0,0 +1,58 @@ +3841\. Palindromic Path Queries in a Tree + +Hard + +You are given an undirected tree with `n` nodes labeled 0 to `n - 1`. This is represented by a 2D array `edges` of length `n - 1`, where edges[i] = [ui, vi] indicates an undirected edge between nodes ui and vi. + +You are also given a string `s` of length `n` consisting of lowercase English letters, where `s[i]` represents the character assigned to node `i`. + +You are also given a string array `queries`, where each `queries[i]` is either: + +* "update ui c": Change the character at node ui to `c`. Formally, update s[ui] = c. +* "query ui vi": Determine whether the string formed by the characters on the **unique** path from ui to vi (inclusive) can be **rearranged** into a **palindrome**. + +Return a boolean array `answer`, where `answer[j]` is `true` if the jth query of type "query ui vi" can be rearranged into a **palindrome**, and `false` otherwise. + +**Example 1:** + +**Input:** n = 3, edges = [[0,1],[1,2]], s = "aac", queries = ["query 0 2","update 1 b","query 0 2"] + +**Output:** [true,false] + +**Explanation:** + +* `"query 0 2"`: Path `0 → 1 → 2` gives `"aac"`, which can be rearranged to form `"aca"`, a palindrome. Thus, `answer[0] = true`. +* `"update 1 b"`: Update node 1 to `'b'`, now `s = "abc"`. +* `"query 0 2"`: Path characters are `"abc"`, which cannot be rearranged to form a palindrome. Thus, `answer[1] = false`. + +Thus, `answer = [true, false]`. + +**Example 2:** + +**Input:** n = 4, edges = [[0,1],[0,2],[0,3]], s = "abca", queries = ["query 1 2","update 0 b","query 2 3","update 3 a","query 1 3"] + +**Output:** [false,false,true] + +**Explanation:** + +* `"query 1 2"`: Path `1 → 0 → 2` gives `"bac"`, which cannot be rearranged to form a palindrome. Thus, `answer[0] = false`. +* `"update 0 b"`: Update node 0 to `'b'`, now `s = "bbca"`. +* `"query 2 3"`: Path `2 → 0 → 3` gives `"cba"`, which cannot be rearranged to form a palindrome. Thus, `answer[1] = false`. +* `"update 3 a"`: Update node 3 to `'a'`, `s = "bbca"`. +* `"query 1 3"`: Path `1 → 0 → 3` gives `"bba"`, which can be rearranged to form `"bab"`, a palindrome. Thus, `answer[2] = true`. + +Thus, `answer = [false, false, true]`. + +**Constraints:** + +* 1 <= n == s.length <= 5 * 104 +* `edges.length == n - 1` +* edges[i] = [ui, vi] +* 0 <= ui, vi <= n - 1 +* `s` consists of lowercase English letters. +* The input is generated such that `edges` represents a valid tree. +* 1 <= queries.length <= 5 * 104 + * queries[i] = "update ui c" or + * queries[i] = "query ui vi" + * 0 <= ui, vi <= n - 1 + * `c` is a lowercase English letter. \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3842_toggle_light_bulbs/Solution.java b/src/main/java/g3801_3900/s3842_toggle_light_bulbs/Solution.java new file mode 100644 index 000000000..8f0bcc294 --- /dev/null +++ b/src/main/java/g3801_3900/s3842_toggle_light_bulbs/Solution.java @@ -0,0 +1,23 @@ +package g3801_3900.s3842_toggle_light_bulbs; + +// #Easy #Array #Hash_Table #Sorting #Simulation #Mid_Level #Weekly_Contest_489 +// #2026_07_22_Time_2_ms_(99.86%)_Space_46.70_MB_(58.12%) + +import java.util.ArrayList; +import java.util.List; + +public class Solution { + public List toggleLightBulbs(List bulbs) { + boolean[] on = new boolean[101]; + for (int b : bulbs) { + on[b] = !on[b]; + } + List ans = new ArrayList<>(); + for (int i = 1; i < 101; ++i) { + if (on[i]) { + ans.add(i); + } + } + return ans; + } +} diff --git a/src/main/java/g3801_3900/s3842_toggle_light_bulbs/readme.md b/src/main/java/g3801_3900/s3842_toggle_light_bulbs/readme.md new file mode 100644 index 000000000..8107a45bf --- /dev/null +++ b/src/main/java/g3801_3900/s3842_toggle_light_bulbs/readme.md @@ -0,0 +1,45 @@ +3842\. Toggle Light Bulbs + +Easy + +You are given an array `bulbs` of integers between 1 and 100. + +There are 100 light bulbs numbered from 1 to 100. All of them are switched off initially. + +For each element `bulbs[i]` in the array `bulbs`: + +* If the bulbs[i]th light bulb is currently off, switch it on. +* Otherwise, switch it off. + +Return the list of integers denoting the light bulbs that are on in the end, **sorted** in **ascending** order. If no bulb is on, return an empty list. + +**Example 1:** + +**Input:** bulbs = [10,30,20,10] + +**Output:** [20,30] + +**Explanation:** + +* The bulbs[0] = 10th light bulb is currently off. We switch it on. +* The bulbs[1] = 30th light bulb is currently off. We switch it on. +* The bulbs[2] = 20th light bulb is currently off. We switch it on. +* The bulbs[3] = 10th light bulb is currently on. We switch it off. +* In the end, the 20th and the 30th light bulbs are on. + +**Example 2:** + +**Input:** bulbs = [100,100] + +**Output:** [] + +**Explanation:** + +* The bulbs[0] = 100th light bulb is currently off. We switch it on. +* The bulbs[1] = 100th light bulb is currently on. We switch it off. +* In the end, no light bulb is on. + +**Constraints:** + +* `1 <= bulbs.length <= 100` +* `1 <= bulbs[i] <= 100` \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/Solution.java b/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/Solution.java new file mode 100644 index 000000000..65892cf83 --- /dev/null +++ b/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/Solution.java @@ -0,0 +1,26 @@ +package g3801_3900.s3843_first_element_with_unique_frequency; + +// #Medium #Array #Hash_Table #Counting #Senior #Weekly_Contest_489 +// #2026_07_22_Time_96_ms_(93.48%)_Space_213.96_MB_(84.60%) + +import java.util.HashMap; +import java.util.Map; + +public class Solution { + public int firstUniqueFreq(int[] nums) { + Map c1 = new HashMap<>(); + for (int a : nums) { + c1.put(a, c1.getOrDefault(a, 0) + 1); + } + Map c2 = new HashMap<>(); + for (int f : c1.values()) { + c2.put(f, c2.getOrDefault(f, 0) + 1); + } + for (int a : nums) { + if (c2.get(c1.get(a)) == 1) { + return a; + } + } + return -1; + } +} diff --git a/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/readme.md b/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/readme.md new file mode 100644 index 000000000..23102aaa2 --- /dev/null +++ b/src/main/java/g3801_3900/s3843_first_element_with_unique_frequency/readme.md @@ -0,0 +1,50 @@ +3843\. First Element with Unique Frequency + +Medium + +You are given an integer array `nums`. + +Return an integer denoting the **first** element (scanning from left to right) in `nums` whose **frequency** is **unique**. That is, no other integer appears the same number of times in `nums`. If there is no such element, return -1. + +**Example 1:** + +**Input:** nums = [20,10,30,30] + +**Output:** 30 + +**Explanation:** + +* 20 appears once. +* 10 appears once. +* 30 appears twice. +* The frequency of 30 is unique because no other integer appears exactly twice. + +**Example 2:** + +**Input:** nums = [20,20,10,30,30,30] + +**Output:** 20 + +**Explanation:** + +* 20 appears twice. +* 10 appears once. +* 30 appears 3 times. +* The frequency of 20, 10, and 30 are unique. The first element that has unique frequency is 20. + +**Example 3:** + +**Input:** nums = [10,10,20,20] + +**Output:** \-1 + +**Explanation:** + +* 10 appears twice. +* 20 appears twice. +* No element has a unique frequency. + +**Constraints:** + +* 1 <= nums.length <= 105 +* 1 <= nums[i] <= 105 \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/Solution.java b/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/Solution.java new file mode 100644 index 000000000..3877aeee9 --- /dev/null +++ b/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/Solution.java @@ -0,0 +1,40 @@ +package g3801_3900.s3844_longest_almost_palindromic_substring; + +// #Medium #String #Dynamic_Programming #Two_Pointers #Staff #Weekly_Contest_489 +// #2026_07_22_Time_10_ms_(99.05%)_Space_44.41_MB_(61.90%) + +public class Solution { + private int n; + private char[] s; + + public int almostPalindromic(String str) { + s = str.toCharArray(); + n = s.length; + int ans = 0; + for (int i = 0; i < n; i++) { + ans = Math.max(ans, f(i, i)); + ans = Math.max(ans, f(i, i + 1)); + } + return ans; + } + + private int f(int l, int r) { + while (l >= 0 && r < n && s[l] == s[r]) { + l--; + r++; + } + int l1 = l - 1; + int r1 = r; + int l2 = l; + int r2 = r + 1; + while (l1 >= 0 && r1 < n && s[l1] == s[r1]) { + l1--; + r1++; + } + while (l2 >= 0 && r2 < n && s[l2] == s[r2]) { + l2--; + r2++; + } + return Math.clamp(Math.max(r1 - l1 - 1, r2 - l2 - 1), 0, n); + } +} diff --git a/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/readme.md b/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/readme.md new file mode 100644 index 000000000..82f411840 --- /dev/null +++ b/src/main/java/g3801_3900/s3844_longest_almost_palindromic_substring/readme.md @@ -0,0 +1,56 @@ +3844\. Longest Almost-Palindromic Substring + +Medium + +You are given a string `s` consisting of lowercase English letters. + +A substring is **almost-palindromic** if it becomes a palindrome after removing **exactly** one character from it. + +Return an integer denoting the length of the **longest** **almost-palindromic** substring in `s`. + +**Example 1:** + +**Input:** s = "abca" + +**Output:** 4 + +**Explanation:** + +Choose the substring "**abca**". + +* Remove "ab**c**a". +* The string becomes `"aba"`, which is a palindrome. +* Therefore, `"abca"` is almost-palindromic. + +**Example 2:** + +**Input:** s = "abba" + +**Output:** 4 + +**Explanation:** + +Choose the substring "**abba**". + +* Remove "a**b**ba". +* The string becomes `"aba"`, which is a palindrome. +* Therefore, `"abba"` is almost-palindromic. + +**Example 3:** + +**Input:** s = "zzabba" + +**Output:** 5 + +**Explanation:** + +Choose the substring "z**zabba**". + +* Remove "**z**abba". +* The string becomes `"abba"`, which is a palindrome. +* Therefore, `"zabba"` is almost-palindromic. + +**Constraints:** + +* `2 <= s.length <= 2500` +* `s` consists of only lowercase English letters. \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/Solution.java b/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/Solution.java new file mode 100644 index 000000000..df151e851 --- /dev/null +++ b/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/Solution.java @@ -0,0 +1,99 @@ +package g3801_3900.s3845_maximum_subarray_xor_with_bounded_range; + +// #Hard #Array #Bit_Manipulation #Prefix_Sum #Sliding_Window #Trie #Queue #Monotonic_Queue +// #Senior_Staff #Weekly_Contest_489 #2026_07_22_Time_130_ms_(98.70%)_Space_64.50_MB_(96.10%) + +import java.util.ArrayDeque; +import java.util.Deque; + +public class Solution { + private static final int BITS = 15; + + static class TrieNode { + TrieNode[] next = new TrieNode[2]; + int count = 0; + } + + private void insert(TrieNode root, int num) { + TrieNode node = root; + for (int i = BITS - 1; i >= 0; i--) { + int bit = (num >> i) & 1; + if (node.next[bit] == null) { + node.next[bit] = new TrieNode(); + } + node = node.next[bit]; + node.count++; + } + } + + private void remove(TrieNode root, int num) { + TrieNode node = root; + for (int i = BITS - 1; i >= 0; i--) { + int bit = (num >> i) & 1; + TrieNode child = node.next[bit]; + child.count--; + if (child.count == 0) { + node.next[bit] = null; + } + node = child; + } + } + + private int query(TrieNode root, int num) { + TrieNode node = root; + int res = 0; + for (int i = BITS - 1; i >= 0; i--) { + int bit = (num >> i) & 1; + if (node.next[bit ^ 1] != null) { + res |= (1 << i); + node = node.next[bit ^ 1]; + } else { + node = node.next[bit]; + } + } + return res; + } + + public int maxXor(int[] nums, int k) { + int n = nums.length; + int[] prefix = new int[n + 1]; + for (int i = 0; i < n; i++) { + prefix[i + 1] = prefix[i] ^ nums[i]; + } + Deque maxDeque = new ArrayDeque<>(); + Deque minDeque = new ArrayDeque<>(); + TrieNode root = new TrieNode(); + int maxXor = 0; + int l = 0; + insert(root, 0); + for (int r = 0; r < n; r++) { + // maintain max deque + while (!maxDeque.isEmpty() && nums[r] > nums[maxDeque.peekLast()]) { + maxDeque.pollLast(); + } + maxDeque.offerLast(r); + // maintain min deque + while (!minDeque.isEmpty() && nums[r] < nums[minDeque.peekLast()]) { + minDeque.pollLast(); + } + minDeque.offerLast(r); + // shrink window if max-min > k + while (!maxDeque.isEmpty() + && !minDeque.isEmpty() + && nums[maxDeque.peekFirst()] - nums[minDeque.peekFirst()] > k) { + remove(root, prefix[l]); + l++; + if (maxDeque.peekFirst() < l) { + maxDeque.pollFirst(); + } + if (minDeque.peekFirst() < l) { + minDeque.pollFirst(); + } + } + // query and insert prefix[r+1] + maxXor = Math.max(maxXor, query(root, prefix[r + 1])); + insert(root, prefix[r + 1]); + } + return maxXor; + } +} diff --git a/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/readme.md b/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/readme.md new file mode 100644 index 000000000..fb1fbcb98 --- /dev/null +++ b/src/main/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/readme.md @@ -0,0 +1,39 @@ +3845\. Maximum Subarray XOR with Bounded Range + +Hard + +You are given a non-negative integer array `nums` and an integer `k`. + +You must select a **non-empty subarrays** of `nums` such that the **difference** between its **maximum** and **minimum** elements is at most `k`. The **value** of this subarray is the bitwise XOR of all elements in the subarray. + +Return an integer denoting the **maximum** possible **value** of the selected subarray. + +**Example 1:** + +**Input:** nums = [5,4,5,6], k = 2 + +**Output:** 7 + +**Explanation:** + +* Select the subarray [5, **4, 5, 6**]. +* The difference between its maximum and minimum elements is `6 - 4 = 2 <= k`. +* The value is `4 XOR 5 XOR 6 = 7`. + +**Example 2:** + +**Input:** nums = [5,4,5,6], k = 1 + +**Output:** 6 + +**Explanation:** + +* Select the subarray [5, 4, 5, **6**]. +* The difference between its maximum and minimum elements is `6 - 6 = 0 <= k`. +* The value is 6. + +**Constraints:** + +* 1 <= nums.length <= 4 * 104 +* 0 <= nums[i] < 215 +* 0 <= k < 215 \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/Solution.java b/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/Solution.java new file mode 100644 index 000000000..1c1c7475d --- /dev/null +++ b/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/Solution.java @@ -0,0 +1,16 @@ +package g3801_3900.s3847_find_the_score_difference_in_a_game; + +// #Medium #Array #Simulation #Senior #Weekly_Contest_490 +// #2026_07_22_Time_1_ms_(100.00%)_Space_46.89_MB_(71.53%) + +public class Solution { + public int scoreDifference(int[] nums) { + int player = 0; + int[] scores = new int[] {0, 0}; + for (int game = 1; game <= nums.length; ++game) { + player ^= ((nums[game - 1] % 2) ^ ((game % 6 == 0) ? 1 : 0)); + scores[player] += nums[game - 1]; + } + return scores[0] - scores[1]; + } +} diff --git a/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/readme.md b/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/readme.md new file mode 100644 index 000000000..c2d42f695 --- /dev/null +++ b/src/main/java/g3801_3900/s3847_find_the_score_difference_in_a_game/readme.md @@ -0,0 +1,58 @@ +3847\. Find the Score Difference in a Game + +Medium + +You are given an integer array `nums`, where `nums[i]` represents the points scored in the ith game. + +There are **exactly** two players. Initially, the first player is **active** and the second player is **inactive**. + +The following rules apply **sequentially** for each game `i`: + +* If `nums[i]` is odd, the active and inactive players swap roles. +* In every 6th game (that is, game indices `5, 11, 17, ...`), the active and inactive players swap roles. +* The active player plays the ith game and gains `nums[i]` points. + +Return the **score difference**, defined as the first player's **total** score **minus** the second player's **total** score. + +**Example 1:** + +**Input:** nums = [1,2,3] + +**Output:** 0 + +**Explanation:** + +* Game 0: Since the points are odd, the second player becomes active and gains `nums[0] = 1` point. +* Game 1: No swap occurs. The second player gains `nums[1] = 2` points. +* Game 2: Since the points are odd, the first player becomes active and gains `nums[2] = 3` points. +* The score difference is `3 - 3 = 0`. + +**Example 2:** + +**Input:** nums = [2,4,2,1,2,1] + +**Output:** 4 + +**Explanation:** + +* Games 0 to 2: The first player gains `2 + 4 + 2 = 8` points. +* Game 3: Since the points are odd, the second player is now active and gains `nums[3] = 1` point. +* Game 4: The second player gains `nums[4] = 2` points. +* Game 5: Since the points are odd, the players swap roles. Then, because this is the 6th game, the players swap again. The second player gains `nums[5] = 1` point. +* The score difference is `8 - 4 = 4`. + +**Example 3:** + +**Input:** nums = [1] + +**Output:** \-1 + +**Explanation:** + +* Game 0: Since the points are odd, the second player is now active and gains `nums[0] = 1` point. +* The score difference is `0 - 1 = -1`. + +**Constraints:** + +* `1 <= nums.length <= 1000` +* `1 <= nums[i] <= 1000` \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3848_check_digitorial_permutation/Solution.java b/src/main/java/g3801_3900/s3848_check_digitorial_permutation/Solution.java new file mode 100644 index 000000000..df7978c97 --- /dev/null +++ b/src/main/java/g3801_3900/s3848_check_digitorial_permutation/Solution.java @@ -0,0 +1,32 @@ +package g3801_3900.s3848_check_digitorial_permutation; + +// #Medium #Math #Counting #Senior #Weekly_Contest_490 +// #2026_07_22_Time_2_ms_(84.89%)_Space_42.70_MB_(97.48%) + +import java.util.Arrays; + +public class Solution { + static int[] digitFrequencies(int x) { + int[] c = new int[10]; + do { + c[x % 10]++; + x /= 10; + } while (x != 0); + return c; + } + + public boolean isDigitorialPermutation(int n) { + int[] factorials = new int[10]; + factorials[0] = 1; + for (int d = 1; d < 10; ++d) { + factorials[d] = factorials[d - 1] * d; + } + int digitsSum = 0; + int x = n; + do { + digitsSum += factorials[x % 10]; + x /= 10; + } while (x != 0); + return Arrays.equals(digitFrequencies(digitsSum), digitFrequencies(n)); + } +} diff --git a/src/main/java/g3801_3900/s3848_check_digitorial_permutation/readme.md b/src/main/java/g3801_3900/s3848_check_digitorial_permutation/readme.md new file mode 100644 index 000000000..39e99d366 --- /dev/null +++ b/src/main/java/g3801_3900/s3848_check_digitorial_permutation/readme.md @@ -0,0 +1,40 @@ +3848\. Check Digitorial Permutation + +Medium + +You are given an integer `n`. + +A number is called **digitorial** if the sum of the **factorials** of its digits is **equal** to the number itself. + +Determine whether **any permutation** of `n` (including the original order) forms a **digitorial** number. + +Return `true` if such a **permutation** exists, otherwise return `false`. + +**Note**: + +* The **factorial** of a non-negative integer `x`, denoted as `x!`, is the **product** of all positive integers **less than or equal** to `x`, and `0! = 1`. +* A **permutation** is a rearrangement of all the digits of a number that does **not** start with zero. Any arrangement starting with zero is invalid. + +**Example 1:** + +**Input:** n = 145 + +**Output:** true + +**Explanation:** + +The number 145 itself is digitorial since `1! + 4! + 5! = 1 + 24 + 120 = 145`. Thus, the answer is `true`. + +**Example 2:** + +**Input:** n = 10 + +**Output:** false + +**Explanation:** + +10 is not digitorial since `1! + 0! = 2` is not equal to 10, and the permutation `"01"` is invalid because it starts with zero. + +**Constraints:** + +* 1 <= n <= 109 \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/Solution.java b/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/Solution.java new file mode 100644 index 000000000..56a9acef5 --- /dev/null +++ b/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/Solution.java @@ -0,0 +1,27 @@ +package g3801_3900.s3849_maximum_bitwise_xor_after_rearrangement; + +// #Medium #String #Greedy #Bit_Manipulation #Staff #Weekly_Contest_490 +// #2026_07_22_Time_32_ms_(96.39%)_Space_55.08_MB_(65.66%) + +public class Solution { + public String maximumXor(String s, String t) { + int[] cnt = new int[2]; + for (char c : t.toCharArray()) { + cnt[c - '0']++; + } + + char[] ans = new char[s.length()]; + for (int i = 0; i < s.length(); i++) { + int x = s.charAt(i) - '0'; + if (cnt[x ^ 1] > 0) { + cnt[x ^ 1]--; + ans[i] = '1'; + } else { + cnt[x]--; + ans[i] = '0'; + } + } + + return new String(ans); + } +} diff --git a/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/readme.md b/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/readme.md new file mode 100644 index 000000000..aa419661c --- /dev/null +++ b/src/main/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/readme.md @@ -0,0 +1,47 @@ +3849\. Maximum Bitwise XOR After Rearrangement + +Medium + +You are given two binary strings `s` and `t`, each of length `n`. + +You may **rearrange** the characters of `t` in any order, but `s` **must remain unchanged**. + +Return a **binary string** of length `n` representing the **maximum** integer value obtainable by taking the bitwise **XOR** of `s` and rearranged `t`. + +**Example 1:** + +**Input:** s = "101", t = "011" + +**Output:** "110" + +**Explanation:** + +* One optimal rearrangement of `t` is `"011"`. +* The bitwise XOR of `s` and rearranged `t` is `"101" XOR "011" = "110"`, which is the maximum possible. + +**Example 2:** + +**Input:** s = "0110", t = "1110" + +**Output:** "1101" + +**Explanation:** + +* One optimal rearrangement of `t` is `"1011"`. +* The bitwise XOR of `s` and rearranged `t` is `"0110" XOR "1011" = "1101"`, which is the maximum possible. + +**Example 3:** + +**Input:** s = "0101", t = "1001" + +**Output:** "1111" + +**Explanation:** + +* One optimal rearrangement of `t` is `"1010"`. +* The bitwise XOR of `s` and rearranged `t` is `"0101" XOR "1010" = "1111"`, which is the maximum possible. + +**Constraints:** + +* 1 <= n == s.length == t.length <= 2 * 105 +* `s[i]` and `t[i]` are either `'0'` or `'1'`. \ No newline at end of file diff --git a/src/main/java/g3801_3900/s3850_count_sequences_to_k/Solution.java b/src/main/java/g3801_3900/s3850_count_sequences_to_k/Solution.java new file mode 100644 index 000000000..658193fde --- /dev/null +++ b/src/main/java/g3801_3900/s3850_count_sequences_to_k/Solution.java @@ -0,0 +1,37 @@ +package g3801_3900.s3850_count_sequences_to_k; + +// #Hard #Array #Dynamic_Programming #Math #Memoization #Number_Theory #Senior_Staff +// #Weekly_Contest_490 #2026_07_22_Time_144_ms_(90.24%)_Space_64.70_MB_(29.27%) + +import java.util.HashMap; +import java.util.Map; + +public class Solution { + + private Map[] dp; + + private int fun(int[] nums, int pos, double val, double k) { + if (pos == nums.length) { + if (Math.abs(val - k) <= 0.000000009) { + return 1; + } + return 0; + } + if (dp[pos].containsKey(val)) { + return dp[pos].get(val); + } + int ret = fun(nums, pos + 1, val, k); + ret += fun(nums, pos + 1, val * nums[pos], k); + ret += fun(nums, pos + 1, val / nums[pos], k); + dp[pos].put(val, ret); + return ret; + } + + public int countSequences(int[] nums, long k) { + dp = new HashMap[22]; + for (int i = 0; i < 22; i++) { + dp[i] = new HashMap<>(); + } + return fun(nums, 0, 1.0, 1.00 * k); + } +} diff --git a/src/main/java/g3801_3900/s3850_count_sequences_to_k/readme.md b/src/main/java/g3801_3900/s3850_count_sequences_to_k/readme.md new file mode 100644 index 000000000..2f5ed6b16 --- /dev/null +++ b/src/main/java/g3801_3900/s3850_count_sequences_to_k/readme.md @@ -0,0 +1,69 @@ +3850\. Count Sequences to K + +Hard + +You are given an integer array `nums`, and an integer `k`. + +Start with an initial value `val = 1` and process `nums` from left to right. At each index `i`, you must choose **exactly one** of the following actions: + +* Multiply `val` by `nums[i]`. +* Divide `val` by `nums[i]`. +* Leave `val` unchanged. + +After processing all elements, `val` is considered **equal** to `k` only if its final rational value **exactly** equals `k`. + +Return the count of **distinct** sequences of choices that result in `val == k`. + +**Note:** Division is rational (exact), not integer division. For example, `2 / 4 = 1 / 2`. + +**Example 1:** + +**Input:** nums = [2,3,2], k = 6 + +**Output:** 2 + +**Explanation:** + +The following 2 distinct sequences of choices result in `val == k`: + +| Sequence | Operation on `nums[0]` | Operation on `nums[1]` | Operation on `nums[2]` | Final `val` | +|----------|-------------------------|-------------------------|-------------------------|-------------| +| 1 | Multiply: `val = 1 * 2 = 2` | Multiply: `val = 2 * 3 = 6` | Leave `val` unchanged | 6 | +| 2 | Leave `val` unchanged | Multiply: `val = 1 * 3 = 3` | Multiply: `val = 3 * 2 = 6` | 6 | + +**Example 2:** + +**Input:** nums = [4,6,3], k = 2 + +**Output:** 2 + +**Explanation:** + +The following 2 distinct sequences of choices result in `val == k`: + +| Sequence | Operation on `nums[0]` | Operation on `nums[1]` | Operation on `nums[2]` | Final `val` | +|----------|-------------------------|-------------------------|-------------------------|-------------| +| 1 | Multiply: `val = 1 * 4 = 4` | Divide: `val = 4 / 6 = 2 / 3` | Multiply: `val = (2 / 3) * 3 = 2` | 2 | +| 2 | Leave `val` unchanged | Multiply: `val = 1 * 6 = 6` | Divide: `val = 6 / 3 = 2` | 2 | + +**Example 3:** + +**Input:** nums = [1,5], k = 1 + +**Output:** 3 + +**Explanation:** + +The following 3 distinct sequences of choices result in `val == k`: + +| Sequence | Operation on `nums[0]` | Operation on `nums[1]` | Final `val` | +|----------|-------------------------|-------------------------|-------------| +| 1 | Multiply: `val = 1 * 1 = 1` | Leave `val` unchanged | 1 | +| 2 | Divide: `val = 1 / 1 = 1` | Leave `val` unchanged | 1 | +| 3 | Leave `val` unchanged | Leave `val` unchanged | 1 | + +**Constraints:** + +* `1 <= nums.length <= 19` +* `1 <= nums[i] <= 6` +* 1 <= k <= 1015 diff --git a/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/Solution.java b/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/Solution.java new file mode 100644 index 000000000..d6f7c25cf --- /dev/null +++ b/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/Solution.java @@ -0,0 +1,26 @@ +package g3801_3900.s3852_smallest_pair_with_different_frequencies; + +// #Easy #Array #Hash_Table #Counting #Mid_Level #Biweekly_Contest_177 +// #2026_07_22_Time_1_ms_(100.00%)_Space_46.80_MB_(62.33%) + +public class Solution { + public int[] minDistinctFreqPair(int[] nums) { + int[] freq = new int[101]; + for (int num : nums) { + freq[num]++; + } + int first = -1; + int second = -1; + for (int i = 1; i <= 100; i++) { + if (freq[i] != 0) { + if (first == -1) { + first = i; + } else if (freq[i] != freq[first]) { + second = i; + break; + } + } + } + return second == -1 ? new int[] {-1, -1} : new int[] {first, second}; + } +} diff --git a/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/readme.md b/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/readme.md new file mode 100644 index 000000000..cac685ab9 --- /dev/null +++ b/src/main/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/readme.md @@ -0,0 +1,52 @@ +3852\. Smallest Pair With Different Frequencies + +Easy + +You are given an integer array `nums`. + +Consider all pairs of **distinct** values `x` and `y` from `nums` such that: + +* `x < y` +* `x` and `y` have different frequencies in `nums`. + +Among all such pairs: + +* Choose the pair with the smallest possible value of `x`. +* If multiple pairs have the same `x`, choose the one with the smallest possible value of `y`. + +Return an integer array `[x, y]`. If no valid pair exists, return `[-1, -1]`. + +**Example 1:** + +**Input:** nums = [1,1,2,2,3,4] + +**Output:** [1,3] + +**Explanation:** + +The smallest value is 1 with a frequency of 2, and the smallest value greater than 1 that has a different frequency from 1 is 3 with a frequency of 1. Thus, the answer is `[1, 3]`. + +**Example 2:** + +**Input:** nums = [1,5] + +**Output:** [-1,-1] + +**Explanation:** + +Both values have the same frequency, so no valid pair exists. Return `[-1, -1]`. + +**Example 3:** + +**Input:** nums = [7] + +**Output:** [-1,-1] + +**Explanation:** + +There is only one value in the array, so no valid pair exists. Return `[-1, -1]`. + +**Constraints:** + +* `1 <= nums.length <= 100` +* `1 <= nums[i] <= 100` \ No newline at end of file diff --git a/src/test/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/SolutionTest.java b/src/test/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/SolutionTest.java new file mode 100644 index 000000000..6e5533766 --- /dev/null +++ b/src/test/java/g3801_3900/s3841_palindromic_path_queries_in_a_tree/SolutionTest.java @@ -0,0 +1,39 @@ +package g3801_3900.s3841_palindromic_path_queries_in_a_tree; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void palindromePath() { + assertThat( + new Solution() + .palindromePath( + 3, + new int[][] {{0, 1}, {1, 2}}, + "aac", + new String[] {"query 0 2", "update 1 b", "query 0 2"}), + equalTo(Arrays.asList(true, false))); + } + + @Test + void palindromePath2() { + assertThat( + new Solution() + .palindromePath( + 4, + new int[][] {{0, 1}, {0, 2}, {0, 3}}, + "abca", + new String[] { + "query 1 2", + "update 0 b", + "query 2 3", + "update 3 a", + "query 1 3" + }), + equalTo(Arrays.asList(false, false, true))); + } +} diff --git a/src/test/java/g3801_3900/s3842_toggle_light_bulbs/SolutionTest.java b/src/test/java/g3801_3900/s3842_toggle_light_bulbs/SolutionTest.java new file mode 100644 index 000000000..88572b05d --- /dev/null +++ b/src/test/java/g3801_3900/s3842_toggle_light_bulbs/SolutionTest.java @@ -0,0 +1,22 @@ +package g3801_3900.s3842_toggle_light_bulbs; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void toggleLightBulbs() { + assertThat( + new Solution().toggleLightBulbs(Arrays.asList(10, 30, 20, 10)), + equalTo(Arrays.asList(20, 30))); + } + + @Test + void toggleLightBulbs2() { + assertThat( + new Solution().toggleLightBulbs(Arrays.asList(100, 100)), equalTo(Arrays.asList())); + } +} diff --git a/src/test/java/g3801_3900/s3843_first_element_with_unique_frequency/SolutionTest.java b/src/test/java/g3801_3900/s3843_first_element_with_unique_frequency/SolutionTest.java new file mode 100644 index 000000000..33c05fde9 --- /dev/null +++ b/src/test/java/g3801_3900/s3843_first_element_with_unique_frequency/SolutionTest.java @@ -0,0 +1,23 @@ +package g3801_3900.s3843_first_element_with_unique_frequency; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void firstUniqueFreq() { + assertThat(new Solution().firstUniqueFreq(new int[] {20, 10, 30, 30}), equalTo(30)); + } + + @Test + void firstUniqueFreq2() { + assertThat(new Solution().firstUniqueFreq(new int[] {20, 20, 10, 30, 30, 30}), equalTo(20)); + } + + @Test + void firstUniqueFreq3() { + assertThat(new Solution().firstUniqueFreq(new int[] {10, 10, 20, 20}), equalTo(-1)); + } +} diff --git a/src/test/java/g3801_3900/s3844_longest_almost_palindromic_substring/SolutionTest.java b/src/test/java/g3801_3900/s3844_longest_almost_palindromic_substring/SolutionTest.java new file mode 100644 index 000000000..921acf1d0 --- /dev/null +++ b/src/test/java/g3801_3900/s3844_longest_almost_palindromic_substring/SolutionTest.java @@ -0,0 +1,23 @@ +package g3801_3900.s3844_longest_almost_palindromic_substring; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void almostPalindromic() { + assertThat(new Solution().almostPalindromic("abca"), equalTo(4)); + } + + @Test + void almostPalindromic2() { + assertThat(new Solution().almostPalindromic("abba"), equalTo(4)); + } + + @Test + void almostPalindromic3() { + assertThat(new Solution().almostPalindromic("zzabba"), equalTo(5)); + } +} diff --git a/src/test/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/SolutionTest.java b/src/test/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/SolutionTest.java new file mode 100644 index 000000000..cbacba4c2 --- /dev/null +++ b/src/test/java/g3801_3900/s3845_maximum_subarray_xor_with_bounded_range/SolutionTest.java @@ -0,0 +1,18 @@ +package g3801_3900.s3845_maximum_subarray_xor_with_bounded_range; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxXor() { + assertThat(new Solution().maxXor(new int[] {5, 4, 5, 6}, 2), equalTo(7)); + } + + @Test + void maxXor2() { + assertThat(new Solution().maxXor(new int[] {5, 4, 5, 6}, 1), equalTo(6)); + } +} diff --git a/src/test/java/g3801_3900/s3847_find_the_score_difference_in_a_game/SolutionTest.java b/src/test/java/g3801_3900/s3847_find_the_score_difference_in_a_game/SolutionTest.java new file mode 100644 index 000000000..7e215c9d0 --- /dev/null +++ b/src/test/java/g3801_3900/s3847_find_the_score_difference_in_a_game/SolutionTest.java @@ -0,0 +1,23 @@ +package g3801_3900.s3847_find_the_score_difference_in_a_game; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void scoreDifference() { + assertThat(new Solution().scoreDifference(new int[] {1, 2, 3}), equalTo(0)); + } + + @Test + void scoreDifference2() { + assertThat(new Solution().scoreDifference(new int[] {2, 4, 2, 1, 2, 1}), equalTo(4)); + } + + @Test + void scoreDifference3() { + assertThat(new Solution().scoreDifference(new int[] {1}), equalTo(-1)); + } +} diff --git a/src/test/java/g3801_3900/s3848_check_digitorial_permutation/SolutionTest.java b/src/test/java/g3801_3900/s3848_check_digitorial_permutation/SolutionTest.java new file mode 100644 index 000000000..79ef5d0f0 --- /dev/null +++ b/src/test/java/g3801_3900/s3848_check_digitorial_permutation/SolutionTest.java @@ -0,0 +1,18 @@ +package g3801_3900.s3848_check_digitorial_permutation; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void isDigitorialPermutation() { + assertThat(new Solution().isDigitorialPermutation(145), equalTo(true)); + } + + @Test + void isDigitorialPermutation2() { + assertThat(new Solution().isDigitorialPermutation(10), equalTo(false)); + } +} diff --git a/src/test/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/SolutionTest.java b/src/test/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/SolutionTest.java new file mode 100644 index 000000000..539c10acb --- /dev/null +++ b/src/test/java/g3801_3900/s3849_maximum_bitwise_xor_after_rearrangement/SolutionTest.java @@ -0,0 +1,23 @@ +package g3801_3900.s3849_maximum_bitwise_xor_after_rearrangement; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maximumXor() { + assertThat(new Solution().maximumXor("101", "011"), equalTo("110")); + } + + @Test + void maximumXor2() { + assertThat(new Solution().maximumXor("0110", "1110"), equalTo("1101")); + } + + @Test + void maximumXor3() { + assertThat(new Solution().maximumXor("0101", "1001"), equalTo("1111")); + } +} diff --git a/src/test/java/g3801_3900/s3850_count_sequences_to_k/SolutionTest.java b/src/test/java/g3801_3900/s3850_count_sequences_to_k/SolutionTest.java new file mode 100644 index 000000000..a5012822c --- /dev/null +++ b/src/test/java/g3801_3900/s3850_count_sequences_to_k/SolutionTest.java @@ -0,0 +1,23 @@ +package g3801_3900.s3850_count_sequences_to_k; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void countSequences() { + assertThat(new Solution().countSequences(new int[] {2, 3, 2}, 6), equalTo(2)); + } + + @Test + void countSequences2() { + assertThat(new Solution().countSequences(new int[] {4, 6, 3}, 2), equalTo(2)); + } + + @Test + void countSequences3() { + assertThat(new Solution().countSequences(new int[] {1, 5}, 1), equalTo(3)); + } +} diff --git a/src/test/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/SolutionTest.java b/src/test/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/SolutionTest.java new file mode 100644 index 000000000..b63e6fd54 --- /dev/null +++ b/src/test/java/g3801_3900/s3852_smallest_pair_with_different_frequencies/SolutionTest.java @@ -0,0 +1,26 @@ +package g3801_3900.s3852_smallest_pair_with_different_frequencies; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minDistinctFreqPair() { + assertThat( + new Solution().minDistinctFreqPair(new int[] {1, 1, 2, 2, 3, 4}), + equalTo(new int[] {1, 3})); + } + + @Test + void minDistinctFreqPair2() { + assertThat( + new Solution().minDistinctFreqPair(new int[] {1, 5}), equalTo(new int[] {-1, -1})); + } + + @Test + void minDistinctFreqPair3() { + assertThat(new Solution().minDistinctFreqPair(new int[] {7}), equalTo(new int[] {-1, -1})); + } +}