Skip to main content
Back to problems
#3614
Hard Algorithms

Process string with special operations ii

String Simulation
16.9% acceptance
Feb 25, 2026
92
8
You are given a string s consisting of lowercase English letters and the special characters: '*', '#', and '%'. You are also given an integer k. Build a new string result by processing s according to the following rules from left to right: If the letter is a lowercase English letter append it to result. A '*' removes the last character from result, if it exists. A '#' duplicates the current result and appends it to itself. A '%' reverses the current result. Return the kth character of the final string result. If k is out of the bounds of result, return '.'.

Solution

Rust
Time O(n)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn process_str(s: String, k: i64) -> char {
    // Simulate operations tracking virtual length and reversed flag
    // We don't store the actual string; instead track snapshots
    // We work backwards: given final index k, trace what character it is
    // Forward pass: record length and operations
    let chars: Vec<char> = s.chars().collect();
    let mut length: i64 = 0;
    let mut ops: Vec<(char, i64)> = Vec::new(); // (op, length_before)
    for &c in &chars {
      match c {
        '*' => {
          if length > 0 {
            ops.push(('*', length));
            length -= 1;
          }
        }
        '#' => {
          ops.push(('#', length));
          length = length.saturating_mul(2);
        }
        '%' => {
          ops.push(('%', length));
        }
        ch  => {
          ops.push((ch, length));
          length += 1;
        }
      }
    }
    if k >= length { return '.'; }
    // Backward pass: find the base character at index k
    let mut idx = k;
    for (op, len_before) in ops.iter().rev() {
      match op {
        '*' => {
          // '*' removed last char, so effective len = len_before - 1
          // length before this op was len_before
          // after op length = len_before - 1
          // idx doesn't change since we removed the last char (len_before-1)
          // actually current used length after was len_before-1, idx < len_before-1
          // before this op len was len_before, same mapping
        }
        '#' => {
          // before: len_before, after: len_before * 2
          // after '%#', idx in [0, 2*len_before-1]
          // maps to idx % len_before in original
          if *len_before == 0 { /* idx stays */ } else {
            idx %= len_before;
          }
        }
        '%' => {
          // after: reversed, len_before is the length
          idx = len_before - 1 - idx;
        }
        ch  => {
          // append character at position len_before
          // after: len = len_before + 1, idx in [0, len_before]
          if idx == *len_before { return *ch; }
          // else idx < len_before, stay in previous
        }
      }
    }
    '.'
  }
}