Skip to content

Commit efb59a8

Browse files
committed
Added tasks 3556-3663
1 parent c56c524 commit efb59a8

File tree

24 files changed

+1133
-0
lines changed

24 files changed

+1133
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package g3501_3600.s3556_sum_of_largest_prime_substrings
2+
3+
// #Medium #2025_05_25_Time_21_ms_(100.00%)_Space_42.82_MB_(100.00%)
4+
5+
class Solution {
6+
fun sumOfLargestPrimes(s: String): Long {
7+
val primeSet: MutableSet<Long> = HashSet<Long>()
8+
val n = s.length
9+
for (i in 0..<n) {
10+
var temp: Long = 0
11+
for (j in i..<n) {
12+
temp = temp * 10 + (s[j].code - '0'.code)
13+
if (isPrime(temp)) {
14+
primeSet.add(temp)
15+
}
16+
}
17+
}
18+
val primes: MutableList<Long> = ArrayList<Long>(primeSet)
19+
primes.sort()
20+
val m = primes.size
21+
if (m < 3) {
22+
var sum: Long = 0
23+
for (p in primes) {
24+
sum += p
25+
}
26+
return sum
27+
}
28+
return primes[m - 1] + primes[m - 2] + primes[m - 3]
29+
}
30+
31+
private fun isPrime(n: Long): Boolean {
32+
if (n < 2) {
33+
return false
34+
}
35+
var i: Long = 2
36+
while (i * i <= n) {
37+
if (n % i == 0L) {
38+
return false
39+
}
40+
++i
41+
}
42+
return true
43+
}
44+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
3556\. Sum of Largest Prime Substrings
2+
3+
Medium
4+
5+
Given a string `s`, find the sum of the **3 largest unique prime numbers** that can be formed using any of its ****substring****.
6+
7+
Return the **sum** of the three largest unique prime numbers that can be formed. If fewer than three exist, return the sum of **all** available primes. If no prime numbers can be formed, return 0.
8+
9+
**Note:** Each prime number should be counted only **once**, even if it appears in **multiple** substrings. Additionally, when converting a substring to an integer, any leading zeros are ignored.
10+
11+
**Example 1:**
12+
13+
**Input:** s = "12234"
14+
15+
**Output:** 1469
16+
17+
**Explanation:**
18+
19+
* The unique prime numbers formed from the substrings of `"12234"` are 2, 3, 23, 223, and 1223.
20+
* The 3 largest primes are 1223, 223, and 23. Their sum is 1469.
21+
22+
**Example 2:**
23+
24+
**Input:** s = "111"
25+
26+
**Output:** 11
27+
28+
**Explanation:**
29+
30+
* The unique prime number formed from the substrings of `"111"` is 11.
31+
* Since there is only one prime number, the sum is 11.
32+
33+
**Constraints:**
34+
35+
* `1 <= s.length <= 10`
36+
* `s` consists of only digits.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package g3501_3600.s3557_find_maximum_number_of_non_intersecting_substrings
2+
3+
import java.util.LinkedList
4+
import kotlin.math.max
5+
6+
// #Medium #2025_05_25_Time_103_ms_(100.00%)_Space_54.87_MB_(100.00%)
7+
8+
class Solution {
9+
fun maxSubstrings(s: String): Int {
10+
val last: Array<LinkedList<Int>> = Array(26) { LinkedList() }
11+
val n = s.length
12+
val dp = IntArray(n + 1)
13+
for (i in 0..<n) {
14+
val c = s[i].code - 'a'.code
15+
dp[i + 1] = dp[i]
16+
for (j in last[c]) {
17+
if (i - j + 1 >= 4) {
18+
dp[i + 1] = max(dp[i + 1], dp[j] + 1)
19+
}
20+
}
21+
last[c].addLast(i)
22+
if (last[c].size > 4) {
23+
last[c].removeFirst()
24+
}
25+
}
26+
return dp[n]
27+
}
28+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
3557\. Find Maximum Number of Non Intersecting Substrings
2+
3+
Medium
4+
5+
You are given a string `word`.
6+
7+
Return the **maximum** number of non-intersecting ****substring**** of word that are at **least** four characters long and start and end with the same letter.
8+
9+
**Example 1:**
10+
11+
**Input:** word = "abcdeafdef"
12+
13+
**Output:** 2
14+
15+
**Explanation:**
16+
17+
The two substrings are `"abcdea"` and `"fdef"`.
18+
19+
**Example 2:**
20+
21+
**Input:** word = "bcdaaaab"
22+
23+
**Output:** 1
24+
25+
**Explanation:**
26+
27+
The only substring is `"aaaa"`. Note that we cannot **also** choose `"bcdaaaab"` since it intersects with the other substring.
28+
29+
**Constraints:**
30+
31+
* <code>1 <= word.length <= 2 * 10<sup>5</sup></code>
32+
* `word` consists only of lowercase English letters.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package g3501_3600.s3558_number_of_ways_to_assign_edge_weights_i
2+
3+
import java.util.*
4+
5+
// #Medium #2025_05_25_Time_118_ms_(100.00%)_Space_122.30_MB_(100.00%)
6+
7+
class Solution {
8+
fun assignEdgeWeights(edges: Array<IntArray>): Int {
9+
val n = edges.size + 1
10+
val adj: MutableList<MutableList<Int?>?> = ArrayList<MutableList<Int?>?>()
11+
for (i in 0..n) {
12+
adj.add(ArrayList<Int?>())
13+
}
14+
for (i in edges) {
15+
adj.get(i[0])!!.add(i[1])
16+
adj.get(i[1])!!.add(i[0])
17+
}
18+
val l = IntArray(n + 1)
19+
var max = 0
20+
Arrays.fill(l, -1)
21+
val q: Queue<IntArray?> = LinkedList<IntArray?>()
22+
q.offer(intArrayOf(1, 0))
23+
l[1] = 0
24+
while (!q.isEmpty()) {
25+
val curr = q.peek()!![0]
26+
val level = q.peek()!![1]
27+
if (l[max] < l[curr]) {
28+
max = curr
29+
}
30+
q.remove()
31+
for (next in adj.get(curr)!!) {
32+
if (l[next!!] != -1) {
33+
continue
34+
}
35+
q.offer(intArrayOf(next, level + 1))
36+
l[next] = level + 1
37+
}
38+
}
39+
val dp: Array<IntArray> = Array<IntArray>(l[max]) { IntArray(2) }
40+
for (i in dp) {
41+
Arrays.fill(i, -1)
42+
}
43+
return solve(0, 0, dp)
44+
}
45+
46+
private fun solve(ind: Int, odd: Int, dp: Array<IntArray>): Int {
47+
if (ind == dp.size) {
48+
if (odd == 1) {
49+
return 1
50+
} else {
51+
return 0
52+
}
53+
}
54+
if (dp[ind][odd] != -1) {
55+
return dp[ind][odd]
56+
}
57+
dp[ind][odd] =
58+
(solve(ind + 1, odd, dp) % MOD + solve(ind + 1, (odd + 1) % 2, dp) % MOD) % MOD
59+
return dp[ind][odd]
60+
}
61+
62+
companion object {
63+
private val MOD = 1e9.toInt() + 7
64+
}
65+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
3558\. Number of Ways to Assign Edge Weights I
2+
3+
Medium
4+
5+
There is an undirected tree with `n` nodes labeled from 1 to `n`, rooted at node 1. The tree is represented by a 2D integer array `edges` of length `n - 1`, where <code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code> indicates that there is an edge between nodes <code>u<sub>i</sub></code> and <code>v<sub>i</sub></code>.
6+
7+
Initially, all edges have a weight of 0. You must assign each edge a weight of either **1** or **2**.
8+
9+
The **cost** of a path between any two nodes `u` and `v` is the total weight of all edges in the path connecting them.
10+
11+
Select any one node `x` at the **maximum** depth. Return the number of ways to assign edge weights in the path from node 1 to `x` such that its total cost is **odd**.
12+
13+
Since the answer may be large, return it **modulo** <code>10<sup>9</sup> + 7</code>.
14+
15+
**Note:** Ignore all edges **not** in the path from node 1 to `x`.
16+
17+
**Example 1:**
18+
19+
![](https://assets.leetcode.com/uploads/2025/03/23/screenshot-2025-03-24-at-060006.png)
20+
21+
**Input:** edges = [[1,2]]
22+
23+
**Output:** 1
24+
25+
**Explanation:**
26+
27+
* The path from Node 1 to Node 2 consists of one edge (`1 → 2`).
28+
* Assigning weight 1 makes the cost odd, while 2 makes it even. Thus, the number of valid assignments is 1.
29+
30+
**Example 2:**
31+
32+
![](https://assets.leetcode.com/uploads/2025/03/23/screenshot-2025-03-24-at-055820.png)
33+
34+
**Input:** edges = [[1,2],[1,3],[3,4],[3,5]]
35+
36+
**Output:** 2
37+
38+
**Explanation:**
39+
40+
* The maximum depth is 2, with nodes 4 and 5 at the same depth. Either node can be selected for processing.
41+
* For example, the path from Node 1 to Node 4 consists of two edges (`1 → 3` and `3 → 4`).
42+
* Assigning weights (1,2) or (2,1) results in an odd cost. Thus, the number of valid assignments is 2.
43+
44+
**Constraints:**
45+
46+
* <code>2 <= n <= 10<sup>5</sup></code>
47+
* `edges.length == n - 1`
48+
* <code>edges[i] == [u<sub>i</sub>, v<sub>i</sub>]</code>
49+
* <code>1 <= u<sub>i</sub>, v<sub>i</sub> <= n</code>
50+
* `edges` represents a valid tree.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package g3501_3600.s3559_number_of_ways_to_assign_edge_weights_ii
2+
3+
import kotlin.math.ceil
4+
import kotlin.math.ln
5+
6+
// #Hard #2025_05_25_Time_135_ms_(100.00%)_Space_119.27_MB_(100.00%)
7+
8+
class Solution {
9+
private var adj: MutableList<MutableList<Int?>?>? = null
10+
private lateinit var level: IntArray
11+
private lateinit var jumps: Array<IntArray?>
12+
13+
private fun mark(node: Int, par: Int) {
14+
for (neigh in adj!!.get(node)!!) {
15+
if (neigh == par) {
16+
continue
17+
}
18+
level[neigh!!] = level[node] + 1
19+
jumps[neigh]!![0] = node
20+
mark(neigh, node)
21+
}
22+
}
23+
24+
fun lift(u: Int, diff: Int): Int {
25+
var u = u
26+
var diff = diff
27+
while (diff > 0) {
28+
val rightmost = diff xor (diff and (diff - 1))
29+
val jump = (ln(rightmost.toDouble()) / ln(2.0)).toInt()
30+
u = jumps[u]!![jump]
31+
diff -= rightmost
32+
}
33+
return u
34+
}
35+
36+
private fun findLca(u: Int, v: Int): Int {
37+
var u = u
38+
var v = v
39+
if (level[u] > level[v]) {
40+
val temp = u
41+
u = v
42+
v = temp
43+
}
44+
v = lift(v, level[v] - level[u])
45+
if (u == v) {
46+
return u
47+
}
48+
for (i in jumps[0]!!.indices.reversed()) {
49+
if (jumps[u]!![i] != jumps[v]!![i]) {
50+
u = jumps[u]!![i]
51+
v = jumps[v]!![i]
52+
}
53+
}
54+
return jumps[u]!![0]
55+
}
56+
57+
private fun findDist(a: Int, b: Int): Int {
58+
return level[a] + level[b] - 2 * level[findLca(a, b)]
59+
}
60+
61+
fun assignEdgeWeights(edges: Array<IntArray>, queries: Array<IntArray>): IntArray {
62+
val n = edges.size + 1
63+
adj = ArrayList<MutableList<Int?>?>()
64+
level = IntArray(n)
65+
for (i in 0..<n) {
66+
adj!!.add(ArrayList<Int?>())
67+
}
68+
for (i in edges) {
69+
adj!!.get(i[0] - 1)!!.add(i[1] - 1)
70+
adj!!.get(i[1] - 1)!!.add(i[0] - 1)
71+
}
72+
val m = (ceil(ln(n - 1.0) / ln(2.0))).toInt() + 1
73+
jumps = Array<IntArray?>(n) { IntArray(m) }
74+
mark(0, -1)
75+
for (j in 1..<m) {
76+
for (i in 0..<n) {
77+
val p = jumps[i]!![j - 1]
78+
jumps[i]!![j] = jumps[p]!![j - 1]
79+
}
80+
}
81+
val pow = IntArray(n + 1)
82+
pow[0] = 1
83+
for (i in 1..n) {
84+
pow[i] = (pow[i - 1] * 2) % MOD
85+
}
86+
val q = queries.size
87+
val ans = IntArray(q)
88+
for (i in 0..<q) {
89+
val d = findDist(queries[i][0] - 1, queries[i][1] - 1)
90+
ans[i] = if (d > 0) pow[d - 1] else 0
91+
}
92+
return ans
93+
}
94+
95+
companion object {
96+
private const val MOD = 1000000007
97+
}
98+
}

0 commit comments

Comments
 (0)