Skip to content

Commit 043da4b

Browse files
authored
Added tasks 3760-3770
1 parent 1cf71a2 commit 043da4b

30 files changed

Lines changed: 1455 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package g3701_3800.s3760_maximum_substrings_with_distinct_start;
2+
3+
// #Medium #String #Hash_Table #Senior #Weekly_Contest_478
4+
// #2026_05_08_Time_5_ms_(98.92%)_Space_47.79_MB_(74.99%)
5+
6+
public class Solution {
7+
public int maxDistinct(String s) {
8+
int mask = 0;
9+
int res = 0;
10+
for (char c : s.toCharArray()) {
11+
int bit = 1 << (c - 'a');
12+
if ((mask & bit) == 0) {
13+
mask |= bit;
14+
res++;
15+
if (res == 26) {
16+
break;
17+
}
18+
}
19+
}
20+
return res;
21+
}
22+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
3760\. Maximum Substrings With Distinct Start
2+
3+
Medium
4+
5+
You are given a string `s` consisting of lowercase English letters.
6+
7+
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).
8+
9+
**Example 1:**
10+
11+
**Input:** s = "abab"
12+
13+
**Output:** 2
14+
15+
**Explanation:**
16+
17+
* Split `"abab"` into `"a"` and `"bab"`.
18+
* Each substring starts with a distinct character i.e `'a'` and `'b'`. Thus, the answer is 2.
19+
20+
**Example 2:**
21+
22+
**Input:** s = "abcd"
23+
24+
**Output:** 4
25+
26+
**Explanation:**
27+
28+
* Split `"abcd"` into `"a"`, `"b"`, `"c"`, and `"d"`.
29+
* Each substring starts with a distinct character. Thus, the answer is 4.
30+
31+
**Example 3:**
32+
33+
**Input:** s = "aaaa"
34+
35+
**Output:** 1
36+
37+
**Explanation:**
38+
39+
* All characters in `"aaaa"` are `'a'`.
40+
* Only one substring can start with `'a'`. Thus, the answer is 1.
41+
42+
**Constraints:**
43+
44+
* <code>1 <= s.length <= 10<sup>5</sup></code>
45+
* `s` consists of lowercase English letters.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package g3701_3800.s3761_minimum_absolute_distance_between_mirror_pairs;
2+
3+
// #Medium #Array #Hash_Table #Math #Staff #Weekly_Contest_478
4+
// #2026_05_08_Time_49_ms_(84.83%)_Space_95.13_MB_(49.31%)
5+
6+
import java.util.HashMap;
7+
8+
public class Solution {
9+
public int minMirrorPairDistance(int[] nums) {
10+
int res = 100000;
11+
int i = 0;
12+
HashMap<Integer, Integer> seen = new HashMap<>();
13+
for (int n : nums) {
14+
int r;
15+
if (seen.containsKey(n)) {
16+
res = Math.min(res, i - seen.get(n));
17+
}
18+
for (r = 0; n > 0; n /= 10) {
19+
r = r * 10 + (n % 10);
20+
}
21+
seen.put(r, i++);
22+
}
23+
24+
return res == 100000 ? -1 : res;
25+
}
26+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
3761\. Minimum Absolute Distance Between Mirror Pairs
2+
3+
Medium
4+
5+
You are given an integer array `nums`.
6+
7+
A **mirror pair** is a pair of indices `(i, j)` such that:
8+
9+
* `0 <= i < j < nums.length`, and
10+
* `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`.
11+
12+
Return the **minimum** absolute distance between the indices of any mirror pair. The absolute distance between indices `i` and `j` is `abs(i - j)`.
13+
14+
If no mirror pair exists, return `-1`.
15+
16+
**Example 1:**
17+
18+
**Input:** nums = [12,21,45,33,54]
19+
20+
**Output:** 1
21+
22+
**Explanation:**
23+
24+
The mirror pairs are:
25+
26+
* (0, 1) since `reverse(nums[0]) = reverse(12) = 21 = nums[1]`, giving an absolute distance `abs(0 - 1) = 1`.
27+
* (2, 4) since `reverse(nums[2]) = reverse(45) = 54 = nums[4]`, giving an absolute distance `abs(2 - 4) = 2`.
28+
29+
The minimum absolute distance among all pairs is 1.
30+
31+
**Example 2:**
32+
33+
**Input:** nums = [120,21]
34+
35+
**Output:** 1
36+
37+
**Explanation:**
38+
39+
There is only one mirror pair (0, 1) since `reverse(nums[0]) = reverse(120) = 21 = nums[1]`.
40+
41+
The minimum absolute distance is 1.
42+
43+
**Example 3:**
44+
45+
**Input:** nums = [21,120]
46+
47+
**Output:** \-1
48+
49+
**Explanation:**
50+
51+
There are no mirror pairs in the array.
52+
53+
**Constraints:**
54+
55+
* <code>1 <= nums.length <= 10<sup>5</sup></code>
56+
* <code>1 <= nums[i] <= 10<sup>9</sup></code>
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package g3701_3800.s3762_minimum_operations_to_equalize_subarrays;
2+
3+
// #Hard #Array #Math #Binary_Search #Segment_Tree #Weekly_Contest_478 #Principal
4+
// #2026_05_08_Time_528_ms_(100.00%)_Space_267.97_MB_(76.92%)
5+
6+
import java.util.ArrayList;
7+
import java.util.Comparator;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
public class Solution {
12+
private static class MNode {
13+
int l;
14+
int r;
15+
int[] vals;
16+
long[] pref;
17+
MNode left;
18+
MNode right;
19+
20+
MNode(int l, int r) {
21+
this.l = l;
22+
this.r = r;
23+
}
24+
}
25+
26+
private static class Group {
27+
int[] pos;
28+
int[] val;
29+
long[] prefPos;
30+
MNode root;
31+
int minv;
32+
int maxv;
33+
}
34+
35+
private static int lowerBound(int[] a, int x) {
36+
int l = 0;
37+
int r = a.length;
38+
while (l < r) {
39+
int m = (l + r) >>> 1;
40+
if (a[m] >= x) {
41+
r = m;
42+
} else {
43+
l = m + 1;
44+
}
45+
}
46+
return l;
47+
}
48+
49+
private int upperBound(int[] a, int x) {
50+
int l = 0;
51+
int r = a.length;
52+
while (l < r) {
53+
int m = (l + r) >>> 1;
54+
if (a[m] > x) {
55+
r = m;
56+
} else {
57+
l = m + 1;
58+
}
59+
}
60+
return l;
61+
}
62+
63+
private MNode buildMerge(int[] arr, int l, int r) {
64+
MNode node = new MNode(l, r);
65+
if (l == r) {
66+
node.vals = new int[] {arr[l]};
67+
node.pref = new long[] {arr[l]};
68+
return node;
69+
}
70+
int m = (l + r) >>> 1;
71+
node.left = buildMerge(arr, l, m);
72+
node.right = buildMerge(arr, m + 1, r);
73+
int[] a = node.left.vals;
74+
int[] b = node.right.vals;
75+
int na = a.length;
76+
int nb = b.length;
77+
int[] c = new int[na + nb];
78+
long[] pref = new long[na + nb];
79+
int ia = 0;
80+
int ib = 0;
81+
int k = 0;
82+
while (ia < na && ib < nb) {
83+
if (a[ia] <= b[ib]) {
84+
c[k++] = a[ia++];
85+
} else {
86+
c[k++] = b[ib++];
87+
}
88+
}
89+
while (ia < na) {
90+
c[k++] = a[ia++];
91+
}
92+
while (ib < nb) {
93+
c[k++] = b[ib++];
94+
}
95+
pref[0] = c[0];
96+
for (int i = 1; i < c.length; i++) {
97+
pref[i] = pref[i - 1] + c[i];
98+
}
99+
node.vals = c;
100+
node.pref = pref;
101+
return node;
102+
}
103+
104+
private int countLE(MNode node, int ql, int qr, int x) {
105+
if (node == null || ql > node.r || qr < node.l) {
106+
return 0;
107+
}
108+
if (ql <= node.l && node.r <= qr) {
109+
int idx = upperBound(node.vals, x) - 1;
110+
return idx < 0 ? 0 : idx + 1;
111+
}
112+
return countLE(node.left, ql, qr, x) + countLE(node.right, ql, qr, x);
113+
}
114+
115+
private long sumLE(MNode node, int ql, int qr, int x) {
116+
if (node == null || ql > node.r || qr < node.l) {
117+
return 0L;
118+
}
119+
if (ql <= node.l && node.r <= qr) {
120+
int idx = upperBound(node.vals, x) - 1;
121+
return idx < 0 ? 0L : node.pref[idx];
122+
}
123+
return sumLE(node.left, ql, qr, x) + sumLE(node.right, ql, qr, x);
124+
}
125+
126+
public long[] minOperations(int[] nums, int k, int[][] queries) {
127+
Map<Integer, Group> groupHashMap = buildGroups(nums, k);
128+
long[] ans = new long[queries.length];
129+
for (int qi = 0; qi < queries.length; qi++) {
130+
ans[qi] = processQuery(nums, queries[qi], groupHashMap, k);
131+
}
132+
return ans;
133+
}
134+
135+
private Map<Integer, Group> buildGroups(int[] nums, int k) {
136+
Map<Integer, ArrayList<int[]>> map = new HashMap<>();
137+
for (int i = 0; i < nums.length; i++) {
138+
int rem = nums[i] % k;
139+
int value = nums[i] / k;
140+
map.computeIfAbsent(rem, z -> new ArrayList<>()).add(new int[] {i, value});
141+
}
142+
Map<Integer, Group> groupHashMap = new HashMap<>();
143+
for (Map.Entry<Integer, ArrayList<int[]>> entry : map.entrySet()) {
144+
groupHashMap.put(entry.getKey(), createGroup(entry.getValue()));
145+
}
146+
return groupHashMap;
147+
}
148+
149+
private Group createGroup(ArrayList<int[]> arr) {
150+
arr.sort(Comparator.comparingInt(a -> a[0]));
151+
int size = arr.size();
152+
int[] pos = new int[size];
153+
int[] val = new int[size];
154+
long[] prefPos = new long[size];
155+
int min = Integer.MAX_VALUE;
156+
int max = Integer.MIN_VALUE;
157+
for (int i = 0; i < size; i++) {
158+
pos[i] = arr.get(i)[0];
159+
val[i] = arr.get(i)[1];
160+
min = Math.min(min, val[i]);
161+
max = Math.max(max, val[i]);
162+
prefPos[i] = i == 0 ? val[i] : prefPos[i - 1] + val[i];
163+
}
164+
Group group = new Group();
165+
group.pos = pos;
166+
group.val = val;
167+
group.prefPos = prefPos;
168+
group.minv = min;
169+
group.maxv = max;
170+
if (size > 0) {
171+
group.root = buildMerge(val, 0, size - 1);
172+
}
173+
return group;
174+
}
175+
176+
private long processQuery(int[] nums, int[] query, Map<Integer, Group> groupHashMap, int k) {
177+
int left = query[0];
178+
int right = query[1];
179+
int rem = nums[left] % k;
180+
Group group = groupHashMap.get(rem);
181+
if (group == null) {
182+
return -1;
183+
}
184+
int l = lowerBound(group.pos, left);
185+
int r = upperBound(group.pos, right) - 1;
186+
if (!isValidRange(left, right, l, r)) {
187+
return -1;
188+
}
189+
return calculateOperations(group, l, r);
190+
}
191+
192+
private boolean isValidRange(int left, int right, int l, int r) {
193+
return l <= r && (r - l + 1 == right - left + 1);
194+
}
195+
196+
private long calculateOperations(Group group, int l, int r) {
197+
int count = r - l + 1;
198+
int median = findMedian(group, l, r, count);
199+
long leftCount = countLE(group.root, l, r, median);
200+
long leftSum = sumLE(group.root, l, r, median);
201+
long total = group.prefPos[r] - (l == 0 ? 0L : group.prefPos[l - 1]);
202+
long rightSum = total - leftSum;
203+
long rightCount = count - leftCount;
204+
return median * leftCount - leftSum + rightSum - median * rightCount;
205+
}
206+
207+
private int findMedian(Group group, int l, int r, int count) {
208+
int need = (count + 1) / 2;
209+
int low = group.minv;
210+
int high = group.maxv;
211+
while (low < high) {
212+
int mid = low + ((high - low) >>> 1);
213+
int currentCount = countLE(group.root, l, r, mid);
214+
if (currentCount >= need) {
215+
high = mid;
216+
} else {
217+
low = mid + 1;
218+
}
219+
}
220+
return low;
221+
}
222+
}

0 commit comments

Comments
 (0)