- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 71 lines of Java from the credited upstream file 3547.java.
- The implementation visibly relies on sequence storage, work queue.
- 7 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public long maxScore(int n, int[][] edges) {3 long ans = 0;4 List<Integer>[] graph = new List[n];5 List<Integer> cycleSizes = new ArrayList<>(); 6 List<Integer> pathSizes = new ArrayList<>(); 7 boolean[] seen = new boolean[n];8 Arrays.setAll(graph, i -> new ArrayList<>());9 10 for (int[] edge : edges) {11 final int u = edge[0];12 final int v = edge[1];13 graph[u].add(v);14 graph[v].add(u);15 }16 17 for (int i = 0; i < n; ++i) {18 if (seen[i])19 continue;20 List<Integer> component = getComponent(graph, i, seen);21 final boolean allDegree2 = component.stream().allMatch(u -> graph[u].size() == 2);22 if (allDegree2)23 cycleSizes.add(component.size());24 else if (component.size() > 1)25 pathSizes.add(component.size());26 }27 28 for (final int cycleSize : cycleSizes) {29 ans += calculateScore(n - cycleSize + 1, n, true);30 n -= cycleSize;31 }32 33 Collections.sort(pathSizes, Collections.reverseOrder());34 35 for (final int pathSize : pathSizes) {36 ans += calculateScore(n - pathSize + 1, n, false);37 n -= pathSize;38 }39 40 return ans;41 }42 43 private List<Integer> getComponent(List<Integer>[] graph, int start, boolean[] seen) {44 List<Integer> component = new ArrayList<>(List.of(start));45 seen[start] = true;46 for (int i = 0; i < component.size(); ++i) {47 final int u = component.get(i);48 for (final int v : graph[u]) {49 if (seen[v])50 continue;51 component.add(v);52 seen[v] = true;53 }54 }55 return component;56 }57 58 private long calculateScore(int left, int right, boolean isCycle) {59 Deque<Long> window = new ArrayDeque<>();60 window.offerLast((long) right);61 window.offerLast((long) right);62 long score = 0;63 for (int value = right - 1; value >= left; --value) {64 final long windowValue = window.pollFirst();65 score += windowValue * value;66 window.offerLast((long) value);67 }68 return score + window.peekFirst() * window.peekLast() * (isCycle ? 1 : 0);69 }70}71