-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsolution.java
More file actions
105 lines (89 loc) · 3.27 KB
/
Copy pathsolution.java
File metadata and controls
105 lines (89 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import java.util.*;
class Solution {
public int maxScore(String s, char[][] jumps) {
int n = s.length();
if (n <= 1)
return 0;
// 1. Prefix sum of ASCII values
int[] pref = new int[n + 1];
for (int i = 0; i < n; i++) {
pref[i + 1] = pref[i] + s.charAt(i);
}
final int ALPHA = 26;
// 2. nextInd[i][c] = next index > i where char ('a' + c) occurs
int[][] nextInd = new int[n][ALPHA];
int[] last = new int[ALPHA];
Arrays.fill(last, -1);
for (int i = n - 1; i >= 0; i--) {
// copy "last" into nextInd[i]
for (int c = 0; c < ALPHA; c++) {
nextInd[i][c] = last[c];
}
int idx = s.charAt(i) - 'a';
if (idx >= 0 && idx < ALPHA) {
last[idx] = i;
}
}
// 3. Character graph: from char -> list of chars it can jump to
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < ALPHA; i++) {
adj.add(new ArrayList<Integer>());
}
if (jumps != null) {
for (int k = 0; k < jumps.length; k++) {
if (jumps[k].length < 2)
continue;
int ui = jumps[k][0] - 'a';
int vi = jumps[k][1] - 'a';
if (ui >= 0 && ui < ALPHA && vi >= 0 && vi < ALPHA) {
adj.get(ui).add(vi);
}
}
}
// always allow same-character jump and remove duplicates
for (int c = 0; c < ALPHA; c++) {
adj.get(c).add(c); // self jump
boolean[] seen = new boolean[ALPHA];
ArrayList<Integer> list = adj.get(c);
ArrayList<Integer> uniq = new ArrayList<>();
for (int x : list) {
if (!seen[x]) {
seen[x] = true;
uniq.add(x);
}
}
adj.set(c, uniq);
}
// 4. DP from right to left
int[] dp = new int[n];
dp[n - 1] = 0; // last index se koi jump nahi
for (int i = n - 2; i >= 0; i--) {
int best = 0;
int fromIdx = s.charAt(i) - 'a';
int fromAscii = s.charAt(i);
// Agar lowercase range se bahar hai toh safe side pe 0
if (fromIdx < 0 || fromIdx >= ALPHA) {
dp[i] = 0;
continue;
}
ArrayList<Integer> edges = adj.get(fromIdx);
for (int t = 0; t < edges.size(); t++) {
int destChar = edges.get(t); // 0..25
int j = nextInd[i][destChar];
if (j == -1)
continue; // koi aage aisa char nahi
// score of substring s[i..j-1]
int gain = pref[j] - pref[i];
// same-character jump pe s[i] ko ignore karna hai
if (destChar == fromIdx) {
gain -= fromAscii;
}
int cand = gain + dp[j];
if (cand > best)
best = cand;
}
dp[i] = best;
}
return dp[0];
}
}