Skip to content

Commit b2f8aea

Browse files
committed
Improved 3394, 3395
1 parent c1ba1de commit b2f8aea

File tree

2 files changed

+76
-157
lines changed
  • src/main/java/g3301_3400

2 files changed

+76
-157
lines changed
Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,40 @@
11
package g3301_3400.s3394_check_if_grid_can_be_cut_into_sections;
22

3-
// #Medium #Geometry #Line_Sweep #2025_01_06_Time_143_(30.90%)_Space_127.26_(32.16%)
3+
// #Medium #Geometry #Line_Sweep #2025_01_06_Time_35_(99.66%)_Space_117.96_(80.52%)
44

55
import java.util.Arrays;
66

7-
@SuppressWarnings({"unused", "java:S1172"})
87
public class Solution {
9-
public boolean checkValidCuts(int n, int[][] rectangles) {
10-
int m = rectangles.length;
11-
int[][] xAxis = new int[m][2];
12-
int[][] yAxis = new int[m][2];
13-
int ind = 0;
14-
for (int[] axis : rectangles) {
15-
int startX = axis[0];
16-
int startY = axis[1];
17-
int endX = axis[2];
18-
int endY = axis[3];
19-
xAxis[ind] = new int[] {startX, endX};
20-
yAxis[ind] = new int[] {startY, endY};
21-
ind++;
8+
private static final int MASK = (1 << 30) - 1;
9+
10+
public boolean checkValidCuts(int m, int[][] rc) {
11+
int n = rc.length;
12+
long[] start = new long[n];
13+
for (int i = 0; i < n; i++) {
14+
start[i] = ((long) rc[i][1] << 32) + rc[i][3];
2215
}
23-
Arrays.sort(xAxis, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
24-
Arrays.sort(yAxis, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
25-
int verticalCuts = findSections(xAxis);
26-
if (verticalCuts > 2) {
16+
Arrays.sort(start);
17+
if (validate(start)) {
2718
return true;
2819
}
29-
int horizontalCuts = findSections(yAxis);
30-
return horizontalCuts > 2;
20+
for (int i = 0; i < n; i++) {
21+
start[i] = ((long) rc[i][0] << 32) + rc[i][2];
22+
}
23+
Arrays.sort(start);
24+
return validate(start);
3125
}
3226

33-
private int findSections(int[][] axis) {
34-
int end = axis[0][1];
35-
int sections = 1;
36-
for (int i = 1; i < axis.length; i++) {
37-
if (end > axis[i][0]) {
38-
end = Math.max(end, axis[i][1]);
39-
} else {
40-
sections++;
41-
end = axis[i][1];
42-
}
43-
if (sections > 2) {
44-
return sections;
27+
private boolean validate(long[] arr) {
28+
int cut = 0;
29+
int n = arr.length;
30+
int max = (int) arr[0] & MASK;
31+
for (int i = 0; i < n; i++) {
32+
int start = (int) (arr[i] >> 32);
33+
if (start >= max && ++cut == 2) {
34+
return true;
4535
}
36+
max = Math.max(max, (int) (arr[i] & MASK));
4637
}
47-
return sections;
38+
return false;
4839
}
4940
}
Lines changed: 51 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,69 @@
11
package g3301_3400.s3395_subsequences_with_a_unique_middle_mode_i;
22

3-
// #Hard #Array #Hash_Table #Math #Combinatorics
4-
// #2025_01_06_Time_1141_(39.01%)_Space_44.78_(100.00%)
3+
// #Hard #Array #Hash_Table #Math #Combinatorics #2025_01_06_Time_27_(99.29%)_Space_45.15_(97.87%)
54

6-
import java.util.ArrayList;
75
import java.util.HashMap;
8-
import java.util.List;
96
import java.util.Map;
107

118
public class Solution {
12-
private static final int MOD = 1000000007;
9+
private static final int MOD = (int) 1e9 + 7;
10+
private long[] c2 = new long[1001];
1311

14-
public int subsequencesWithMiddleMode(int[] a) {
15-
int n = a.length;
16-
// Create a dictionary to store indices of each number
17-
Map<Integer, List<Integer>> dict = new HashMap<>();
18-
for (int i = 0; i < n; i++) {
19-
dict.computeIfAbsent(a[i], k -> new ArrayList<>()).add(i);
20-
}
21-
long ans = 0L;
22-
// Iterate over each unique number and its indices
23-
for (Map.Entry<Integer, List<Integer>> entry : dict.entrySet()) {
24-
List<Integer> b = entry.getValue();
25-
int m = b.size();
26-
for (int k = 0; k < m; k++) {
27-
int i = b.get(k);
28-
int r = m - 1 - k;
29-
int u = i - k;
30-
int v = (n - 1 - i) - r;
31-
// Case 2: Frequency of occurrence is 2 times
32-
ans = (ans + convert(k, 1) * convert(u, 1) % MOD * convert(v, 2) % MOD) % MOD;
33-
ans = (ans + convert(r, 1) * convert(u, 2) % MOD * convert(v, 1) % MOD) % MOD;
34-
// Case 3: Frequency of occurrence is 3 times
35-
ans = (ans + convert(k, 2) * convert(v, 2) % MOD) % MOD;
36-
ans = (ans + convert(r, 2) * convert(u, 2) % MOD) % MOD;
37-
ans =
38-
(ans
39-
+ convert(k, 1)
40-
* convert(r, 1)
41-
% MOD
42-
* convert(u, 1)
43-
% MOD
44-
* convert(v, 1)
45-
% MOD)
46-
% MOD;
47-
48-
// Case 4: Frequency of occurrence is 4 times
49-
ans = (ans + convert(k, 2) * convert(r, 1) % MOD * convert(v, 1) % MOD) % MOD;
50-
ans = (ans + convert(k, 1) * convert(r, 2) % MOD * convert(u, 1) % MOD) % MOD;
51-
52-
// Case 5: Frequency of occurrence is 5 times
53-
ans = (ans + convert(k, 2) * convert(r, 2) % MOD) % MOD;
12+
public int subsequencesWithMiddleMode(int[] nums) {
13+
if (c2[2] == 0) {
14+
c2[0] = c2[1] = 0;
15+
c2[2] = 1;
16+
for (int i = 3; i < c2.length; ++i) {
17+
c2[i] = i * (i - 1) / 2;
5418
}
5519
}
56-
long dif = 0;
57-
// Principle of inclusion-exclusion
58-
for (Map.Entry<Integer, List<Integer>> midEntry : dict.entrySet()) {
59-
List<Integer> b = midEntry.getValue();
60-
int m = b.size();
61-
for (Map.Entry<Integer, List<Integer>> tmpEntry : dict.entrySet()) {
62-
if (!midEntry.getKey().equals(tmpEntry.getKey())) {
63-
List<Integer> c = tmpEntry.getValue();
64-
int size = c.size();
65-
int k = 0;
66-
int j = 0;
67-
while (k < m) {
68-
int i = b.get(k);
69-
int r = m - 1 - k;
70-
int u = i - k;
71-
int v = (n - 1 - i) - r;
72-
while (j < size && c.get(j) < i) {
73-
j++;
74-
}
75-
int x = j;
76-
int y = size - x;
77-
dif =
78-
(dif
79-
+ convert(k, 1)
80-
* convert(x, 1)
81-
% MOD
82-
* convert(y, 1)
83-
% MOD
84-
* convert(v - y, 1)
85-
% MOD)
86-
% MOD;
87-
dif =
88-
(dif
89-
+ convert(k, 1)
90-
* convert(y, 2)
91-
% MOD
92-
* convert(u - x, 1)
93-
% MOD)
94-
% MOD;
95-
dif =
96-
(dif + convert(k, 1) * convert(x, 1) % MOD * convert(y, 2) % MOD)
97-
% MOD;
98-
99-
dif =
100-
(dif
101-
+ convert(r, 1)
102-
* convert(x, 1)
103-
% MOD
104-
* convert(y, 1)
105-
% MOD
106-
* convert(u - x, 1)
107-
% MOD)
108-
% MOD;
109-
dif =
110-
(dif
111-
+ convert(r, 1)
112-
* convert(x, 2)
113-
% MOD
114-
* convert(v - y, 1)
115-
% MOD)
116-
% MOD;
117-
dif =
118-
(dif + convert(r, 1) * convert(x, 2) % MOD * convert(y, 1) % MOD)
119-
% MOD;
120-
k++;
121-
}
122-
}
20+
int n = nums.length;
21+
int[] newNums = new int[n];
22+
Map<Integer, Integer> map = new HashMap<>(n);
23+
int m = 0;
24+
int index = 0;
25+
for (int x : nums) {
26+
Integer id = map.get(x);
27+
if (id == null) {
28+
id = m++;
29+
map.put(x, id);
12330
}
31+
newNums[index++] = id;
12432
}
125-
return (int) ((ans - dif + MOD) % MOD);
126-
}
127-
128-
private long convert(int n, int k) {
129-
if (k > n) {
33+
if (m == n) {
13034
return 0;
13135
}
132-
if (k == 0 || k == n) {
133-
return 1;
36+
int[] rightCount = new int[m];
37+
for (int x : newNums) {
38+
rightCount[x]++;
13439
}
135-
long res = 1;
136-
for (int i = 0; i < k; i++) {
137-
res = res * (n - i) / (i + 1);
40+
int[] leftCount = new int[m];
41+
long ans = (long) n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120;
42+
for (int left = 0; left < n - 2; left++) {
43+
int x = newNums[left];
44+
rightCount[x]--;
45+
if (left >= 2) {
46+
int right = n - (left + 1);
47+
int leftX = leftCount[x];
48+
int rightX = rightCount[x];
49+
ans -= c2[left - leftX] * c2[right - rightX];
50+
for (int y = 0; y < m; ++y) {
51+
if (y == x) {
52+
continue;
53+
}
54+
int rightY = rightCount[y];
55+
int leftY = leftCount[y];
56+
ans -= c2[leftY] * rightX * (right - rightX);
57+
ans -= c2[rightY] * leftX * (left - leftX);
58+
ans -=
59+
leftY
60+
* rightY
61+
* (leftX * (right - rightX - rightY)
62+
+ rightX * (left - leftX - leftY));
63+
}
64+
}
65+
leftCount[x]++;
13866
}
139-
return res % MOD;
67+
return (int) (ans % MOD);
14068
}
14169
}

0 commit comments

Comments
 (0)