Skip to content

Commit 4114229

Browse files
committed
Added tasks 3556-3663
1 parent f414bf5 commit 4114229

File tree

24 files changed

+1044
-0
lines changed

24 files changed

+1044
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
import java.util.ArrayList;
6+
import java.util.Collections;
7+
import java.util.HashSet;
8+
import java.util.List;
9+
import java.util.Set;
10+
11+
public class Solution {
12+
public long sumOfLargestPrimes(String s) {
13+
Set<Long> primeSet = new HashSet<>();
14+
int n = s.length();
15+
for (int i = 0; i < n; ++i) {
16+
long temp = 0;
17+
for (int j = i; j < n; ++j) {
18+
temp = temp * 10 + (s.charAt(j) - '0');
19+
if (isPrime(temp)) {
20+
primeSet.add(temp);
21+
}
22+
}
23+
}
24+
List<Long> primes = new ArrayList<>(primeSet);
25+
Collections.sort(primes);
26+
int m = primes.size();
27+
if (m < 3) {
28+
long sum = 0;
29+
for (long p : primes) {
30+
sum += p;
31+
}
32+
return sum;
33+
}
34+
return primes.get(m - 1) + primes.get(m - 2) + primes.get(m - 3);
35+
}
36+
37+
private boolean isPrime(long n) {
38+
if (n < 2) {
39+
return false;
40+
}
41+
for (long i = 2; i * i <= n; ++i) {
42+
if (n % i == 0) {
43+
return false;
44+
}
45+
}
46+
return true;
47+
}
48+
}
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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package g3501_3600.s3557_find_maximum_number_of_non_intersecting_substrings;
2+
3+
// #Medium #2025_05_25_Time_103_ms_(100.00%)_Space_54.87_MB_(100.00%)
4+
5+
import java.util.Deque;
6+
import java.util.LinkedList;
7+
8+
@SuppressWarnings("unchecked")
9+
public class Solution {
10+
public int maxSubstrings(String s) {
11+
Deque<Integer>[] last = new LinkedList[26];
12+
for (int k = 0; k < 26; k++) {
13+
last[k] = new LinkedList<>();
14+
}
15+
int n = s.length();
16+
int[] dp = new int[n + 1];
17+
for (int i = 0; i < n; i++) {
18+
int c = s.charAt(i) - 'a';
19+
dp[i + 1] = dp[i];
20+
for (int j : last[c]) {
21+
if (i - j + 1 >= 4) {
22+
dp[i + 1] = Math.max(dp[i + 1], dp[j] + 1);
23+
}
24+
}
25+
last[c].addLast(i);
26+
if (last[c].size() > 4) {
27+
last[c].removeFirst();
28+
}
29+
}
30+
return dp[n];
31+
}
32+
}
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: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package g3501_3600.s3558_number_of_ways_to_assign_edge_weights_i;
2+
3+
// #Medium #2025_05_25_Time_118_ms_(100.00%)_Space_122.30_MB_(100.00%)
4+
5+
import java.util.ArrayList;
6+
import java.util.Arrays;
7+
import java.util.LinkedList;
8+
import java.util.List;
9+
import java.util.Queue;
10+
11+
public class Solution {
12+
private static final int MOD = (int) 1e9 + 7;
13+
14+
public int assignEdgeWeights(int[][] edges) {
15+
int n = edges.length + 1;
16+
List<List<Integer>> adj = new ArrayList<>();
17+
for (int i = 0; i <= n; i++) {
18+
adj.add(new ArrayList<Integer>());
19+
}
20+
for (int[] i : edges) {
21+
adj.get(i[0]).add(i[1]);
22+
adj.get(i[1]).add(i[0]);
23+
}
24+
int[] l = new int[n + 1];
25+
int max = 0;
26+
Arrays.fill(l, -1);
27+
Queue<int[]> q = new LinkedList<int[]>();
28+
q.offer(new int[] {1, 0});
29+
l[1] = 0;
30+
while (!q.isEmpty()) {
31+
int curr = q.peek()[0];
32+
int level = q.peek()[1];
33+
if (l[max] < l[curr]) {
34+
max = curr;
35+
}
36+
q.remove();
37+
for (int next : adj.get(curr)) {
38+
if (l[next] != -1) {
39+
continue;
40+
}
41+
q.offer(new int[] {next, level + 1});
42+
l[next] = level + 1;
43+
}
44+
}
45+
int[][] dp = new int[l[max]][2];
46+
for (int[] i : dp) {
47+
Arrays.fill(i, -1);
48+
}
49+
return solve(0, 0, dp);
50+
}
51+
52+
private int solve(int ind, int odd, int[][] dp) {
53+
if (ind == dp.length) {
54+
if (odd == 1) {
55+
return 1;
56+
} else {
57+
return 0;
58+
}
59+
}
60+
if (dp[ind][odd] != -1) {
61+
return dp[ind][odd];
62+
}
63+
dp[ind][odd] =
64+
(solve(ind + 1, odd, dp) % MOD + solve(ind + 1, (odd + 1) % 2, dp) % MOD) % MOD;
65+
return dp[ind][odd];
66+
}
67+
}
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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package g3501_3600.s3559_number_of_ways_to_assign_edge_weights_ii;
2+
3+
// #Hard #2025_05_25_Time_135_ms_(100.00%)_Space_119.27_MB_(100.00%)
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class Solution {
9+
private static final int MOD = 1000000007;
10+
private List<List<Integer>> adj;
11+
private int[] level;
12+
private int jumps[][];
13+
14+
private void mark(int node, int par) {
15+
for (int neigh : adj.get(node)) {
16+
if (neigh == par) {
17+
continue;
18+
}
19+
level[neigh] = level[node] + 1;
20+
jumps[neigh][0] = node;
21+
mark(neigh, node);
22+
}
23+
}
24+
25+
public int lift(int u, int diff) {
26+
while (diff > 0) {
27+
int rightmost = diff ^ (diff & (diff - 1));
28+
int jump = (int) (Math.log(rightmost) / Math.log(2));
29+
u = jumps[u][jump];
30+
diff -= rightmost;
31+
}
32+
return u;
33+
}
34+
35+
private int findLca(int u, int v) {
36+
if (level[u] > level[v]) {
37+
int temp = u;
38+
u = v;
39+
v = temp;
40+
}
41+
v = lift(v, level[v] - level[u]);
42+
if (u == v) {
43+
return u;
44+
}
45+
for (int i = jumps[0].length - 1; i >= 0; i--) {
46+
if (jumps[u][i] != jumps[v][i]) {
47+
u = jumps[u][i];
48+
v = jumps[v][i];
49+
}
50+
}
51+
return jumps[u][0];
52+
}
53+
54+
private int findDist(int a, int b) {
55+
56+
return level[a] + level[b] - 2 * level[findLca(a, b)];
57+
}
58+
59+
public int[] assignEdgeWeights(int[][] edges, int[][] queries) {
60+
int n = edges.length + 1;
61+
adj = new ArrayList<>();
62+
level = new int[n];
63+
for (int i = 0; i < n; i++) {
64+
adj.add(new ArrayList<>());
65+
}
66+
for (int i[] : edges) {
67+
adj.get(i[0] - 1).add(i[1] - 1);
68+
adj.get(i[1] - 1).add(i[0] - 1);
69+
}
70+
int m = (int) (Math.ceil(Math.log(n - 1) / Math.log(2))) + 1;
71+
jumps = new int[n][m];
72+
mark(0, -1);
73+
for (int j = 1; j < m; j++) {
74+
for (int i = 0; i < n; i++) {
75+
int p = jumps[i][j - 1];
76+
jumps[i][j] = jumps[p][j - 1];
77+
}
78+
}
79+
int pow[] = new int[n + 1];
80+
pow[0] = 1;
81+
for (int i = 1; i <= n; i++) {
82+
pow[i] = (pow[i - 1] * 2) % MOD;
83+
}
84+
int q = queries.length;
85+
int ans[] = new int[q];
86+
for (int i = 0; i < q; i++) {
87+
int d = findDist(queries[i][0] - 1, queries[i][1] - 1);
88+
ans[i] = d > 0 ? pow[d - 1] : 0;
89+
}
90+
return ans;
91+
}
92+
}

0 commit comments

Comments
 (0)