Skip to content

Commit 7aefaaf

Browse files
authored
Added tasks 3597-3600
1 parent 244a4ed commit 7aefaaf

File tree

12 files changed

+575
-0
lines changed

12 files changed

+575
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package g3501_3600.s3597_partition_string
2+
3+
// #Medium #String #Hash_Table #Simulation #Trie
4+
// #2025_06_30_Time_43_ms_(100.00%)_Space_61.32_MB_(100.00%)
5+
6+
class Solution {
7+
private class Trie {
8+
var tries: Array<Trie?> = arrayOfNulls<Trie>(26)
9+
}
10+
11+
fun partitionString(s: String): List<String> {
12+
val trie = Trie()
13+
val res: MutableList<String> = ArrayList()
14+
var node: Trie = trie
15+
var i = 0
16+
var j = 0
17+
while (i < s.length && j < s.length) {
18+
val idx = s[j].code - 'a'.code
19+
if (node.tries[idx] == null) {
20+
res.add(s.substring(i, j + 1))
21+
node.tries[idx] = Trie()
22+
i = j + 1
23+
j = i
24+
node = trie
25+
} else {
26+
node = node.tries[idx]!!
27+
j++
28+
}
29+
}
30+
return res
31+
}
32+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
3597\. Partition String
2+
3+
Medium
4+
5+
Given a string `s`, partition it into **unique segments** according to the following procedure:
6+
7+
* Start building a segment beginning at index 0.
8+
* Continue extending the current segment character by character until the current segment has not been seen before.
9+
* Once the segment is unique, add it to your list of segments, mark it as seen, and begin a new segment from the next index.
10+
* Repeat until you reach the end of `s`.
11+
12+
Return an array of strings `segments`, where `segments[i]` is the <code>i<sup>th</sup></code> segment created.
13+
14+
**Example 1:**
15+
16+
**Input:** s = "abbccccd"
17+
18+
**Output:** ["a","b","bc","c","cc","d"]
19+
20+
**Explanation:**
21+
22+
Here is your table, converted from HTML to Markdown:
23+
24+
| Index | Segment After Adding | Seen Segments | Current Segment Seen Before? | New Segment | Updated Seen Segments |
25+
|-------|----------------------|-----------------------|------------------------------|-------------|----------------------------------|
26+
| 0 | "a" | [] | No | "" | ["a"] |
27+
| 1 | "b" | ["a"] | No | "" | ["a", "b"] |
28+
| 2 | "b" | ["a", "b"] | Yes | "b" | ["a", "b"] |
29+
| 3 | "bc" | ["a", "b"] | No | "" | ["a", "b", "bc"] |
30+
| 4 | "c" | ["a", "b", "bc"] | No | "" | ["a", "b", "bc", "c"] |
31+
| 5 | "c" | ["a", "b", "bc", "c"] | Yes | "c" | ["a", "b", "bc", "c"] |
32+
| 6 | "cc" | ["a", "b", "bc", "c"] | No | "" | ["a", "b", "bc", "c", "cc"] |
33+
| 7 | "d" | ["a", "b", "bc", "c", "cc"] | No | "" | ["a", "b", "bc", "c", "cc", "d"] |
34+
35+
Hence, the final output is `["a", "b", "bc", "c", "cc", "d"]`.
36+
37+
**Example 2:**
38+
39+
**Input:** s = "aaaa"
40+
41+
**Output:** ["a","aa"]
42+
43+
**Explanation:**
44+
45+
Here is your table converted to Markdown:
46+
47+
| Index | Segment After Adding | Seen Segments | Current Segment Seen Before? | New Segment | Updated Seen Segments |
48+
|-------|----------------------|---------------|------------------------------|-------------|----------------------|
49+
| 0 | "a" | [] | No | "" | ["a"] |
50+
| 1 | "a" | ["a"] | Yes | "a" | ["a"] |
51+
| 2 | "aa" | ["a"] | No | "" | ["a", "aa"] |
52+
| 3 | "a" | ["a", "aa"] | Yes | "a" | ["a", "aa"] |
53+
54+
Hence, the final output is `["a", "aa"]`.
55+
56+
**Constraints:**
57+
58+
* <code>1 <= s.length <= 10<sup>5</sup></code>
59+
* `s` contains only lowercase English letters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package g3501_3600.s3598_longest_common_prefix_between_adjacent_strings_after_removals
2+
3+
// #Medium #Array #String #2025_06_30_Time_28_ms_(71.43%)_Space_81.21_MB_(71.43%)
4+
5+
import kotlin.math.max
6+
import kotlin.math.min
7+
8+
class Solution {
9+
private fun solve(a: String, b: String): Int {
10+
val len = min(a.length, b.length)
11+
var cnt = 0
12+
while (cnt < len && a[cnt] == b[cnt]) {
13+
cnt++
14+
}
15+
return cnt
16+
}
17+
18+
fun longestCommonPrefix(words: Array<String>): IntArray {
19+
val n = words.size
20+
val ans = IntArray(n)
21+
if (n <= 1) {
22+
return ans
23+
}
24+
val lcp = IntArray(n - 1)
25+
run {
26+
var i = 0
27+
while (i + 1 < n) {
28+
lcp[i] = solve(words[i], words[i + 1])
29+
i++
30+
}
31+
}
32+
val prefmax = IntArray(n - 1)
33+
val sufmax = IntArray(n - 1)
34+
prefmax[0] = lcp[0]
35+
for (i in 1..<n - 1) {
36+
prefmax[i] = max(prefmax[i - 1], lcp[i])
37+
}
38+
sufmax[n - 2] = lcp[n - 2]
39+
for (i in n - 3 downTo 0) {
40+
sufmax[i] = max(sufmax[i + 1], lcp[i])
41+
}
42+
for (i in 0..<n) {
43+
var best = 0
44+
if (i >= 2) {
45+
best = max(best, prefmax[i - 2])
46+
}
47+
if (i + 1 <= n - 2) {
48+
best = max(best, sufmax[i + 1])
49+
}
50+
if (i > 0 && i < n - 1) {
51+
best = max(best, solve(words[i - 1], words[i + 1]))
52+
}
53+
ans[i] = best
54+
}
55+
return ans
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
3598\. Longest Common Prefix Between Adjacent Strings After Removals
2+
3+
Medium
4+
5+
You are given an array of strings `words`. For each index `i` in the range `[0, words.length - 1]`, perform the following steps:
6+
7+
* Remove the element at index `i` from the `words` array.
8+
* Compute the **length** of the **longest common prefix** among all **adjacent** pairs in the modified array.
9+
10+
Return an array `answer`, where `answer[i]` is the length of the longest common prefix between the adjacent pairs after removing the element at index `i`. If **no** adjacent pairs remain or if **none** share a common prefix, then `answer[i]` should be 0.
11+
12+
**Example 1:**
13+
14+
**Input:** words = ["jump","run","run","jump","run"]
15+
16+
**Output:** [3,0,0,3,3]
17+
18+
**Explanation:**
19+
20+
* Removing index 0:
21+
* `words` becomes `["run", "run", "jump", "run"]`
22+
* Longest adjacent pair is `["run", "run"]` having a common prefix `"run"` (length 3)
23+
* Removing index 1:
24+
* `words` becomes `["jump", "run", "jump", "run"]`
25+
* No adjacent pairs share a common prefix (length 0)
26+
* Removing index 2:
27+
* `words` becomes `["jump", "run", "jump", "run"]`
28+
* No adjacent pairs share a common prefix (length 0)
29+
* Removing index 3:
30+
* `words` becomes `["jump", "run", "run", "run"]`
31+
* Longest adjacent pair is `["run", "run"]` having a common prefix `"run"` (length 3)
32+
* Removing index 4:
33+
* words becomes `["jump", "run", "run", "jump"]`
34+
* Longest adjacent pair is `["run", "run"]` having a common prefix `"run"` (length 3)
35+
36+
**Example 2:**
37+
38+
**Input:** words = ["dog","racer","car"]
39+
40+
**Output:** [0,0,0]
41+
42+
**Explanation:**
43+
44+
* Removing any index results in an answer of 0.
45+
46+
**Constraints:**
47+
48+
* <code>1 <= words.length <= 10<sup>5</sup></code>
49+
* <code>1 <= words[i].length <= 10<sup>4</sup></code>
50+
* `words[i]` consists of lowercase English letters.
51+
* The sum of `words[i].length` is smaller than or equal <code>10<sup>5</sup></code>.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package g3501_3600.s3599_partition_array_to_minimize_xor
2+
3+
// #Medium #Array #Dynamic_Programming #Bit_Manipulation #Prefix_Sum
4+
// #2025_06_30_Time_136_ms_(100.00%)_Space_54.66_MB_(100.00%)
5+
6+
import kotlin.math.max
7+
import kotlin.math.min
8+
9+
class Solution {
10+
fun minXor(nums: IntArray, k: Int): Int {
11+
val n = nums.size
12+
// Step 1: Prefix XOR array
13+
val pfix = IntArray(n + 1)
14+
for (i in 1..n) {
15+
pfix[i] = pfix[i - 1] xor nums[i - 1]
16+
}
17+
// Step 2: DP table
18+
val dp: Array<IntArray> = Array(n + 1) { IntArray(k + 1) }
19+
for (row in dp) {
20+
row.fill(Int.Companion.MAX_VALUE)
21+
}
22+
for (i in 0..n) {
23+
// Base case: 1 partition
24+
dp[i][1] = pfix[i]
25+
}
26+
// Step 3: Fill DP for partitions 2 to k
27+
for (parts in 2..k) {
28+
for (end in parts..n) {
29+
for (split in parts - 1..<end) {
30+
val segmentXOR = pfix[end] xor pfix[split]
31+
val maxXOR = max(dp[split][parts - 1], segmentXOR)
32+
dp[end][parts] = min(dp[end][parts], maxXOR)
33+
}
34+
}
35+
}
36+
return dp[n][k]
37+
}
38+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
3599\. Partition Array to Minimize XOR
2+
3+
Medium
4+
5+
You are given an integer array `nums` and an integer `k`.
6+
7+
Your task is to partition `nums` into `k` non-empty ****non-empty subarrays****. For each subarray, compute the bitwise **XOR** of all its elements.
8+
9+
Return the **minimum** possible value of the **maximum XOR** among these `k` subarrays.
10+
11+
**Example 1:**
12+
13+
**Input:** nums = [1,2,3], k = 2
14+
15+
**Output:** 1
16+
17+
**Explanation:**
18+
19+
The optimal partition is `[1]` and `[2, 3]`.
20+
21+
* XOR of the first subarray is `1`.
22+
* XOR of the second subarray is `2 XOR 3 = 1`.
23+
24+
The maximum XOR among the subarrays is 1, which is the minimum possible.
25+
26+
**Example 2:**
27+
28+
**Input:** nums = [2,3,3,2], k = 3
29+
30+
**Output:** 2
31+
32+
**Explanation:**
33+
34+
The optimal partition is `[2]`, `[3, 3]`, and `[2]`.
35+
36+
* XOR of the first subarray is `2`.
37+
* XOR of the second subarray is `3 XOR 3 = 0`.
38+
* XOR of the third subarray is `2`.
39+
40+
The maximum XOR among the subarrays is 2, which is the minimum possible.
41+
42+
**Example 3:**
43+
44+
**Input:** nums = [1,1,2,3,1], k = 2
45+
46+
**Output:** 0
47+
48+
**Explanation:**
49+
50+
The optimal partition is `[1, 1]` and `[2, 3, 1]`.
51+
52+
* XOR of the first subarray is `1 XOR 1 = 0`.
53+
* XOR of the second subarray is `2 XOR 3 XOR 1 = 0`.
54+
55+
The maximum XOR among the subarrays is 0, which is the minimum possible.
56+
57+
**Constraints:**
58+
59+
* `1 <= nums.length <= 250`
60+
* <code>1 <= nums[i] <= 10<sup>9</sup></code>
61+
* `1 <= k <= n`

0 commit comments

Comments
 (0)