Post

Reverse Thinking

Maximum Segment Sum After Removals

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
private long[] parents;

public long[] maximumSegmentSum(int[] nums, int[] removeQueries) {
    // reverse union-find
    int n = nums.length;
    this.parents = new long[n];
    // max long is used to mark unvisited
    Arrays.fill(parents, Long.MAX_VALUE);

    long[] answer = new long[n];
    for (int i = n - 1; i > 0; i--) {
        int q = removeQueries[i];
        parents[q] = -nums[q];

        // unions with left interval
        if (q > 0 && parents[q - 1] != Long.MAX_VALUE) {
            union(q, q - 1);
        }

        // unions with right interval
        if (q < n - 1 && parents[q + 1] != Long.MAX_VALUE) {
            union(q, q + 1);
        }

        answer[i - 1] = Math.max(answer[i], -parents[find(q)]);
    }
    return answer;
}

private int find(int u) {
    return parents[u] < 0 ? u : (int)(parents[u] = find((int)parents[u]));
}

private void union(int u, int v) {
    int pu = find(u), pv = find(v);
    // negated sum
    parents[pv] += parents[pu];
    parents[pu] = pv;
}

This problem can also be resolved by TreeMap of intervals.

Execution of All Suffix Instructions Staying in a Grid

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
// notice the direction is opposition to the instruction
// because we will process the instructions in reverse order
private static final Map<Character, int[]> DIRECTIONS = Map.of(
    'U', new int[]{1, 0},
    'L', new int[]{0, 1},
    'D', new int[]{-1, 0},
    'R', new int[]{0, -1}
);

public int[] executeInstructions(int n, int[] startPos, String s) {
    // offset[i]: steps to move off the grid from the start position in the i-th direction
    // {top, left, bottom, right}
    //
    // assume the grid has no boundary
    int[] offsets = {startPos[0] + 1, startPos[1] + 1, startPos[0] - n, startPos[1] - n};

    int m = s.length();
    // maps[i]: {pos[i], last seen instruction index when robot is at pos[i]}
    Map<Integer, Integer>[] maps = new Map[2];
    maps[0] = new HashMap<>();  // horizontal
    maps[1] = new HashMap<>();  // vertical
    maps[0].put(0, m);
    maps[1].put(0, m);

    // virtualPos[i]: the virtual location that if the robot starts here at the i-th instruction
    //    finally it will reach (0, 0) following the remaining instruction sequence
    //
    // assume the robot starts from the i-th instruction and ends at the top border (-1) at a certain instruction
    // at the i-th time, the mirror robot is at (pos[0], pos[1])
    // now we are computing which row is the end row of virtual robot
    // denote the end position of mirror as (virtualEnd[0], virtualEnd[1])
    // in the vertical direction, we have:
    //  startPos[0] - (-1) = virtualPos[0] - virtualEnd[0]
    //  virtualEnd[0] = virtualPos[0] - (startPos[0] + 1)
    //    = virtualPos[0] - offset[top]
    //
    // now we processes the instructions in reverse order
    int[] virtualPos = new int[2], answer = new int[m];
    for (int i = m - 1; i >= 0; i--) {
        int[] instr = DIRECTIONS.get(s.charAt(i));
        virtualPos[0] += instr[0];
        virtualPos[1] += instr[1];

        int min = m - i;
        for (int j = 0; j < offsets.length; j++) {
            // 2 * m - (i + 1) >= m, so we use it as the default value
            // if there was an instruction with index j when virtualPos equals this threshold (virtualPos - offset)
            // then the real robot will be at border at index j
            // so the feasible instructions are (j - i - 1)
            min = Math.min(min, maps[j % 2].getOrDefault(virtualPos[j % 2] - offsets[j], 2 * m) - i - 1);
        }

        maps[0].put(virtualPos[0], i);
        maps[1].put(virtualPos[1], i);
        answer[i] = min;
    }
    return answer;
}

For example, n = 2, startPos = [1,1], s = "LURD"

Steps

We can see at each instruction, the virtual robot will eventually reach (0, 0) following the remaining instruction sequence.

Sum of Matrix After Queries

This post is licensed under CC BY 4.0 by the author.