Skip to content

Commit fbc3266

Browse files
authored
Improved task 3392-3405
1 parent 6a18290 commit fbc3266

File tree

12 files changed

+95
-221
lines changed
  • src/main/kotlin
    • g3301_3400
      • s3392_count_subarrays_of_length_three_with_a_condition
      • s3393_count_paths_with_the_given_xor_value
      • s3394_check_if_grid_can_be_cut_into_sections
      • s3395_subsequences_with_a_unique_middle_mode_i
      • s3396_minimum_number_of_operations_to_make_elements_in_array_distinct
      • s3397_maximum_number_of_distinct_elements_after_operations
      • s3398_smallest_substring_with_identical_characters_i
      • s3399_smallest_substring_with_identical_characters_ii
    • g3401_3500
      • s3402_minimum_operations_to_make_columns_strictly_increasing
      • s3403_find_the_lexicographically_largest_string_from_the_box_i
      • s3404_count_special_subsequences
      • s3405_count_the_number_of_arrays_with_k_matching_adjacent_elements

12 files changed

+95
-221
lines changed

src/main/kotlin/g3301_3400/s3392_count_subarrays_of_length_three_with_a_condition/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3301_3400.s3392_count_subarrays_of_length_three_with_a_condition
22

3-
// #Easy #2024_12_22_Time_3_ms_(100.00%)_Space_45_MB_(100.00%)
3+
// #Easy #Array #2024_12_22_Time_3_ms_(100.00%)_Space_45_MB_(100.00%)
44

55
class Solution {
66
fun countSubarrays(nums: IntArray): Int {

src/main/kotlin/g3301_3400/s3393_count_paths_with_the_given_xor_value/Solution.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package g3301_3400.s3393_count_paths_with_the_given_xor_value
22

3-
// #Medium #2024_12_30_Time_57_(68.42%)_Space_73.12_(52.63%)
3+
// #Medium #Array #Dynamic_Programming #Math #Matrix #Bit_Manipulation
4+
// #2024_12_30_Time_57_(68.42%)_Space_73.12_(52.63%)
45

56
class Solution {
67
private var m = -1
Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,43 @@
11
package g3301_3400.s3394_check_if_grid_can_be_cut_into_sections
22

3-
// #Medium #2024_12_22_Time_298_ms_(100.00%)_Space_132.4_MB_(100.00%)
3+
// #Medium #Geometry #Line_Sweep #2025_01_06_Time_61_(100.00%)_Space_152.17_(45.00%)
44

55
import kotlin.math.max
66

77
@Suppress("unused")
88
class Solution {
9-
fun checkValidCuts(n: Int, rectangles: Array<IntArray>): Boolean {
10-
val m = rectangles.size
11-
val xAxis = Array<IntArray>(m) { IntArray(2) }
12-
val yAxis = Array<IntArray>(m) { IntArray(2) }
13-
var ind = 0
14-
for (axis in rectangles) {
15-
val startX = axis[0]
16-
val startY = axis[1]
17-
val endX = axis[2]
18-
val endY = axis[3]
19-
xAxis[ind] = intArrayOf(startX, endX)
20-
yAxis[ind] = intArrayOf(startY, endY)
21-
ind++
9+
fun checkValidCuts(m: Int, rectangles: Array<IntArray>): Boolean {
10+
val n = rectangles.size
11+
val start = LongArray(n)
12+
for (i in 0..<n) {
13+
start[i] = (rectangles[i][1].toLong() shl 32) + rectangles[i][3]
2214
}
23-
24-
xAxis.sortWith<IntArray>(
25-
Comparator { a: IntArray, b: IntArray -> if (a[0] == b[0]) a[1] - b[1] else a[0] - b[0] },
26-
)
27-
28-
yAxis.sortWith<IntArray>(
29-
Comparator { a: IntArray, b: IntArray -> if (a[0] == b[0]) a[1] - b[1] else a[0] - b[0] },
30-
)
31-
val verticalCuts = findSections(xAxis)
32-
if (verticalCuts > 2) {
15+
start.sort()
16+
if (validate(start)) {
3317
return true
3418
}
35-
val horizontalCuts = findSections(yAxis)
36-
return horizontalCuts > 2
19+
for (i in 0..<n) {
20+
start[i] = (rectangles[i][0].toLong() shl 32) + rectangles[i][2]
21+
}
22+
start.sort()
23+
return validate(start)
3724
}
3825

39-
private fun findSections(axis: Array<IntArray>): Int {
40-
var end = axis[0][1]
41-
var sections = 1
42-
for (i in 1..<axis.size) {
43-
if (end > axis[i][0]) {
44-
end = max(end, axis[i][1])
45-
} else {
46-
sections++
47-
end = axis[i][1]
48-
}
49-
if (sections > 2) {
50-
return sections
26+
private fun validate(arr: LongArray): Boolean {
27+
var cut = 0
28+
val n = arr.size
29+
var max = arr[0].toInt() and MASK
30+
for (i in 0..<n) {
31+
val start = (arr[i] shr 32).toInt()
32+
if (start >= max && ++cut == 2) {
33+
return true
5134
}
35+
max = max(max.toDouble(), (arr[i] and MASK.toLong()).toInt().toDouble()).toInt()
5236
}
53-
return sections
37+
return false
38+
}
39+
40+
companion object {
41+
private val MASK = (1 shl 30) - 1
5442
}
5543
}
Lines changed: 56 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,190 +1,74 @@
11
package g3301_3400.s3395_subsequences_with_a_unique_middle_mode_i
22

3-
// #Hard #2024_12_22_Time_485_ms_(100.00%)_Space_50.6_MB_(100.00%)
3+
// #Hard #Array #Hash_Table #Math #Combinatorics #2025_01_06_Time_49_(100.00%)_Space_41.14_(100.00%)
44

55
class Solution {
6-
fun subsequencesWithMiddleMode(a: IntArray): Int {
7-
val n = a.size
8-
// Create a dictionary to store indices of each number
9-
val dict: MutableMap<Int, MutableList<Int>> = HashMap()
10-
for (i in 0..<n) {
11-
dict.computeIfAbsent(a[i]) { _: Int -> ArrayList<Int>() }.add(i)
12-
}
13-
var ans = 0L
14-
// Iterate over each unique number and its indices
15-
for (entry in dict.entries) {
16-
val b: MutableList<Int> = entry.value
17-
val m = b.size
18-
for (k in 0..<m) {
19-
val i: Int = b[k]
20-
val r = m - 1 - k
21-
val u = i - k
22-
val v = (n - 1 - i) - r
23-
// Case 2: Frequency of occurrence is 2 times
24-
ans = (
25-
ans + convert(k, 1) * convert(u, 1) % MOD * convert(
26-
v,
27-
2,
28-
) % MOD
29-
) % MOD
30-
ans = (
31-
ans + convert(r, 1) * convert(u, 2) % MOD * convert(
32-
v,
33-
1,
34-
) % MOD
35-
) % MOD
36-
// Case 3: Frequency of occurrence is 3 times
37-
ans = (ans + convert(k, 2) * convert(v, 2) % MOD) % MOD
38-
ans = (ans + convert(r, 2) * convert(u, 2) % MOD) % MOD
39-
ans =
40-
(
41-
(
42-
ans +
43-
convert(k, 1) *
44-
convert(r, 1) %
45-
MOD
46-
* convert(u, 1) %
47-
MOD
48-
* convert(v, 1) %
49-
MOD
50-
) %
51-
MOD
52-
)
53-
// Case 4: Frequency of occurrence is 4 times
54-
ans = (
55-
ans + convert(k, 2) * convert(r, 1) % MOD * convert(
56-
v,
57-
1,
58-
) % MOD
59-
) % MOD
60-
ans = (
61-
ans + convert(k, 1) * convert(r, 2) % MOD * convert(
62-
u,
63-
1,
64-
) % MOD
65-
) % MOD
6+
private val c2 = LongArray(1001)
667

67-
// Case 5: Frequency of occurrence is 5 times
68-
ans = (ans + convert(k, 2) * convert(r, 2) % MOD) % MOD
8+
fun subsequencesWithMiddleMode(nums: IntArray): Int {
9+
if (c2[2] == 0L) {
10+
c2[1] = 0
11+
c2[0] = c2[1]
12+
c2[2] = 1
13+
for (i in 3..<c2.size) {
14+
c2[i] = (i * (i - 1) / 2).toLong()
6915
}
7016
}
71-
var dif: Long = 0
72-
// Principle of inclusion-exclusion
73-
for (midEntry in dict.entries) {
74-
val b: MutableList<Int> = midEntry.value
75-
val m = b.size
76-
for (tmpEntry in dict.entries) {
77-
if (midEntry.key != tmpEntry.key) {
78-
val c: MutableList<Int> = tmpEntry.value
79-
val size = c.size
80-
var k = 0
81-
var j = 0
82-
while (k < m) {
83-
val i: Int = b[k]
84-
val r = m - 1 - k
85-
val u = i - k
86-
val v = (n - 1 - i) - r
87-
while (j < size && c[j] < i) {
88-
j++
89-
}
90-
val x = j
91-
val y = size - x
92-
dif =
93-
(
94-
(
95-
dif +
96-
convert(k, 1) *
97-
convert(x, 1) %
98-
MOD
99-
* convert(y, 1) %
100-
MOD
101-
* convert(v - y, 1) %
102-
MOD
103-
) %
104-
MOD
105-
)
106-
dif =
107-
(
108-
(
109-
dif +
110-
convert(k, 1) *
111-
convert(y, 2) %
112-
MOD
113-
* convert(u - x, 1) %
114-
MOD
115-
) %
116-
MOD
117-
)
118-
dif =
119-
(
120-
(
121-
dif + convert(k, 1) * convert(x, 1) % MOD * convert(
122-
y,
123-
2,
124-
) % MOD
125-
) %
126-
MOD
127-
)
128-
129-
dif =
130-
(
131-
(
132-
dif +
133-
convert(r, 1) *
134-
convert(x, 1) %
135-
MOD
136-
* convert(y, 1) %
137-
MOD
138-
* convert(u - x, 1) %
139-
MOD
140-
) %
141-
MOD
142-
)
143-
dif =
144-
(
145-
(
146-
dif +
147-
convert(r, 1) *
148-
convert(x, 2) %
149-
MOD
150-
* convert(v - y, 1) %
151-
MOD
152-
) %
153-
MOD
154-
)
155-
dif =
156-
(
157-
(
158-
dif + convert(r, 1) * convert(x, 2) % MOD * convert(
159-
y,
160-
1,
161-
) % MOD
162-
) %
163-
MOD
164-
)
165-
k++
166-
}
167-
}
17+
val n = nums.size
18+
val newNums = IntArray(n)
19+
val map: MutableMap<Int?, Int?> = HashMap<Int?, Int?>(n)
20+
var m = 0
21+
var index = 0
22+
for (x in nums) {
23+
var id = map[x]
24+
if (id == null) {
25+
id = m++
26+
map.put(x, id)
16827
}
28+
newNums[index++] = id
16929
}
170-
return ((ans - dif + MOD) % MOD).toInt()
171-
}
172-
173-
private fun convert(n: Int, k: Int): Long {
174-
if (k > n) {
30+
if (m == n) {
17531
return 0
17632
}
177-
if (k == 0 || k == n) {
178-
return 1
33+
val rightCount = IntArray(m)
34+
for (x in newNums) {
35+
rightCount[x]++
17936
}
180-
var res: Long = 1
181-
for (i in 0..<k) {
182-
res = res * (n - i) / (i + 1)
37+
val leftCount = IntArray(m)
38+
var ans = n.toLong() * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120
39+
for (left in 0..<n - 2) {
40+
val x = newNums[left]
41+
rightCount[x]--
42+
if (left >= 2) {
43+
val right = n - (left + 1)
44+
val leftX = leftCount[x]
45+
val rightX = rightCount[x]
46+
ans -= c2[left - leftX] * c2[right - rightX]
47+
for (y in 0..<m) {
48+
if (y == x) {
49+
continue
50+
}
51+
val rightY = rightCount[y]
52+
val leftY = leftCount[y]
53+
ans -= c2[leftY] * rightX * (right - rightX)
54+
ans -= c2[rightY] * leftX * (left - leftX)
55+
ans -=
56+
(
57+
leftY
58+
* rightY
59+
* (
60+
leftX * (right - rightX - rightY) +
61+
rightX * (left - leftX - leftY)
62+
)
63+
).toLong()
64+
}
65+
}
66+
leftCount[x]++
18367
}
184-
return res % MOD
68+
return (ans % MOD).toInt()
18569
}
18670

18771
companion object {
188-
private const val MOD = 1000000007
72+
private val MOD = 1e9.toInt() + 7
18973
}
19074
}

src/main/kotlin/g3301_3400/s3396_minimum_number_of_operations_to_make_elements_in_array_distinct/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3301_3400.s3396_minimum_number_of_operations_to_make_elements_in_array_distinct
22

3-
// #Easy #2024_12_22_Time_9_ms_(100.00%)_Space_37.9_MB_(100.00%)
3+
// #Easy #Array #Greedy #Simulation #2024_12_22_Time_9_ms_(100.00%)_Space_37.9_MB_(100.00%)
44

55
import kotlin.math.min
66

src/main/kotlin/g3301_3400/s3397_maximum_number_of_distinct_elements_after_operations/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3301_3400.s3397_maximum_number_of_distinct_elements_after_operations
22

3-
// #Medium #2024_12_22_Time_517_ms_(100.00%)_Space_61.2_MB_(100.00%)
3+
// #Medium #Array #Sorting #Greedy #2024_12_22_Time_517_ms_(100.00%)_Space_61.2_MB_(100.00%)
44

55
import kotlin.math.max
66

src/main/kotlin/g3301_3400/s3398_smallest_substring_with_identical_characters_i/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3301_3400.s3398_smallest_substring_with_identical_characters_i
22

3-
// #Hard #2024_12_24_Time_2_ms_(100.00%)_Space_36.4_MB_(92.86%)
3+
// #Hard #Array #Binary_Search #Enumeration #2024_12_24_Time_2_ms_(100.00%)_Space_36.4_MB_(92.86%)
44

55
class Solution {
66
fun minLength(s: String, ops: Int): Int {

src/main/kotlin/g3301_3400/s3399_smallest_substring_with_identical_characters_ii/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3301_3400.s3399_smallest_substring_with_identical_characters_ii
22

3-
// #Hard #2024_12_24_Time_26_ms_(100.00%)_Space_40.2_MB_(100.00%)
3+
// #Hard #Bit_Manipulation #Sliding_Window #2024_12_24_Time_26_ms_(100.00%)_Space_40.2_MB_(100.00%)
44

55
import kotlin.math.max
66
import kotlin.math.min

src/main/kotlin/g3401_3500/s3402_minimum_operations_to_make_columns_strictly_increasing/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3401_3500.s3402_minimum_operations_to_make_columns_strictly_increasing
22

3-
// #Easy #2024_12_29_Time_1_(100.00%)_Space_44.94_(100.00%)
3+
// #Easy #Matrix #Simulation #2024_12_29_Time_1_(100.00%)_Space_44.94_(100.00%)
44

55
class Solution {
66
fun minimumOperations(grid: Array<IntArray>): Int {

src/main/kotlin/g3401_3500/s3403_find_the_lexicographically_largest_string_from_the_box_i/Solution.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3401_3500.s3403_find_the_lexicographically_largest_string_from_the_box_i
22

3-
// #Medium #2024_12_29_Time_22_(100.00%)_Space_38.72_(100.00%)
3+
// #Medium #String #Two_Pointers #Enumeration #2024_12_29_Time_22_(100.00%)_Space_38.72_(100.00%)
44

55
import kotlin.math.min
66

0 commit comments

Comments
 (0)