Process String with Special Operations II

Hard
Watch on YouTube ↗

Solution

class Solution {
    public char processStr(String s, long k) {

        // Forward pass: simulate all operations to find final string length
        // Time: O(n), Space: O(1)
        long len = 0;
        for (char ch : s.toCharArray()) {
            if (ch >= 'a' && ch <= 'z') len++;
            else if (ch == '#')         len = len * 2;
            else if (ch == '*')         { if (len > 0) len--; }
            // '%' (reverse) does not affect length
        }

        // k is out of bounds — position doesn't exist in final string
        if (k >= len) return '.';

        // Backward pass: trace where index k came from before each operation
        for (int i = s.length() - 1; i >= 0; i--) {
            char ch = s.charAt(i);

            if (ch == '*') {
                // '*' deleted the last char, so undo by incrementing length
                len++;
            } else if (ch == '#') {
                // '#' doubled the string — undo by halving
                len = len / 2;
                // If k was in the second half, map it back to the first half
                if (k >= len) k = k - len;
            } else if (ch == '%') {
                // '%' reversed the string — undo by mirroring index
                k = len - 1 - k;
            } else {
                // Letter: it occupied the last slot before being appended
                len--;
                if (len == k) return ch;
            }
        }

        return '.';
    }
}