From 105bc64f2baa18e31c002fc4baa6c6a2d2bffecf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 16 Jun 2026 05:45:23 +0000 Subject: [PATCH] feat: add solution for 3612. Process String with Special Operations I --- .../analysis_daily_20260616.md | 70 ++++++++++++++++++ .../problem.md | 74 +++++++++++++++++++ .../solution_daily_20260616.go | 34 +++++++++ .../solution_daily_20260616_test.go | 29 ++++++++ 4 files changed, 207 insertions(+) create mode 100644 problems/3612-process-string-with-special-operations-i/analysis_daily_20260616.md create mode 100644 problems/3612-process-string-with-special-operations-i/problem.md create mode 100644 problems/3612-process-string-with-special-operations-i/solution_daily_20260616.go create mode 100644 problems/3612-process-string-with-special-operations-i/solution_daily_20260616_test.go diff --git a/problems/3612-process-string-with-special-operations-i/analysis_daily_20260616.md b/problems/3612-process-string-with-special-operations-i/analysis_daily_20260616.md new file mode 100644 index 0000000..e1204d3 --- /dev/null +++ b/problems/3612-process-string-with-special-operations-i/analysis_daily_20260616.md @@ -0,0 +1,70 @@ +# 3612. Process String with Special Operations I + +[LeetCode Link](https://leetcode.com/problems/process-string-with-special-operations-i/) + +Difficulty: Medium +Topics: String, Simulation + +Acceptance Rate: 68.3% + +## Hints + +### Hint 1 + +This problem is asking you to *replay* a sequence of instructions one by one and watch how a string evolves. When a problem describes a list of rules applied "from left to right," it is usually a **simulation** problem — you don't need a clever formula, you need to faithfully model what each character does. + +### Hint 2 + +Think about which data structure makes each of the four operations cheap and easy to express: + +- appending a letter, +- removing the last character, +- duplicating the whole string, +- reversing the whole string. + +A growable sequence of bytes (a slice/`[]byte` or string builder) handles all of these naturally. The only operation you must be careful with is removal, since the string might be empty. + +### Hint 3 + +The whole solution is a single pass over `s` with a `switch` on the current character. The key insight is that the constraints are tiny (`s.length <= 20`), so you can afford to literally perform each operation, even the ones that look expensive like duplicate and reverse. There is no hidden trick — correctness and careful edge-case handling (empty `result` on `*`) are what matter. + +## Approach + +Maintain a mutable buffer (`result`) that starts empty. Walk through `s` left to right and apply each character: + +1. **Lowercase letter** — append it to `result`. +2. **`'*'`** — remove the last character of `result`, *but only if `result` is non-empty*. Removing from an empty buffer is a no-op. +3. **`'#'`** — duplicate `result` by appending a copy of it to itself (`result = result + result`). +4. **`'%'`** — reverse `result` in place. + +After the loop, `result` is the answer. + +Walking through Example 1, `s = "a#b%*"`: + +| Step | Char | Operation | `result` | +|------|------|-----------|----------| +| 0 | `a` | append | `"a"` | +| 1 | `#` | duplicate | `"aa"` | +| 2 | `b` | append | `"aab"` | +| 3 | `%` | reverse | `"baa"` | +| 4 | `*` | remove last | `"ba"` | + +Final answer: `"ba"`. + +Using a `[]byte` buffer keeps every operation simple: append is `append(...)`, remove is a length truncation `result = result[:len(result)-1]`, duplicate is `append(result, result...)`, and reverse is a standard two-pointer swap. Each maps directly to the rule it implements, which keeps the code readable and easy to verify. + +## Complexity Analysis + +Let `n = len(s)`. The buffer can grow when `#` duplicates it. In the worst case the length doubles on a `#`, so the final length is bounded by `O(2^n)`, but with `n <= 20` this is a small, fixed bound. + +Time Complexity: O(n + L) where `L` is the total work done across duplicate/reverse operations on the buffer. Each `#` and `%` touches at most the current buffer length, so the total is proportional to the sum of buffer sizes seen — bounded by the final length. With the given constraints this is effectively constant-bounded and very fast. + +Space Complexity: O(L) for the buffer holding the result, where `L` is the final string length. + +## Edge Cases + +- **`'*'` on an empty `result`**: Must be a no-op. Forgetting the empty check causes an index-out-of-range panic (slicing `result[:len(result)-1]` when `len == 0`). See Example 2 where `z*` empties the buffer before further ops. +- **`'#'` on an empty `result`**: Duplicating `""` yields `""` — naturally handled, but worth confirming your code doesn't special-case it incorrectly. +- **`'%'` on an empty or single-character `result`**: Reversing should leave it unchanged; a correct two-pointer loop handles this automatically. +- **A buffer that becomes empty mid-processing** then receives more letters: ensure appends still work after the buffer was emptied. +- **Strings consisting only of special characters** (e.g. `"*%#"`): the result stays empty throughout. diff --git a/problems/3612-process-string-with-special-operations-i/problem.md b/problems/3612-process-string-with-special-operations-i/problem.md new file mode 100644 index 0000000..49296dd --- /dev/null +++ b/problems/3612-process-string-with-special-operations-i/problem.md @@ -0,0 +1,74 @@ +--- +number: "3612" +frontend_id: "3612" +title: "Process String with Special Operations I" +slug: "process-string-with-special-operations-i" +difficulty: "Medium" +topics: + - "String" + - "Simulation" +acceptance_rate: 6833.9 +is_premium: false +created_at: "2026-06-16T05:43:49.433883+00:00" +fetched_at: "2026-06-16T05:43:49.433883+00:00" +link: "https://leetcode.com/problems/process-string-with-special-operations-i/" +date: "2026-06-16" +--- + +# 3612. Process String with Special Operations I + +You are given a string `s` consisting of lowercase English letters and the special characters: `*`, `#`, and `%`. + +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 final string `result` after processing all characters in `s`. + + + +**Example 1:** + +**Input:** s = "a#b%*" + +**Output:** "ba" + +**Explanation:** + +`i` | `s[i]` | Operation | Current `result` +---|---|---|--- +0 | `'a'` | Append `'a'` | `"a"` +1 | `'#'` | Duplicate `result` | `"aa"` +2 | `'b'` | Append `'b'` | `"aab"` +3 | `'%'` | Reverse `result` | `"baa"` +4 | `'*'` | Remove the last character | `"ba"` + +Thus, the final `result` is `"ba"`. + +**Example 2:** + +**Input:** s = "z*#" + +**Output:** "" + +**Explanation:** + +`i` | `s[i]` | Operation | Current `result` +---|---|---|--- +0 | `'z'` | Append `'z'` | `"z"` +1 | `'*'` | Remove the last character | `""` +2 | `'#'` | Duplicate the string | `""` + +Thus, the final `result` is `""`. + + + +**Constraints:** + + * `1 <= s.length <= 20` + * `s` consists of only lowercase English letters and special characters `*`, `#`, and `%`. diff --git a/problems/3612-process-string-with-special-operations-i/solution_daily_20260616.go b/problems/3612-process-string-with-special-operations-i/solution_daily_20260616.go new file mode 100644 index 0000000..a2b6cde --- /dev/null +++ b/problems/3612-process-string-with-special-operations-i/solution_daily_20260616.go @@ -0,0 +1,34 @@ +package main + +// 3612. Process String with Special Operations I +// +// Approach: straightforward left-to-right simulation. We maintain a []byte +// buffer `result` and apply each character of s: +// - lowercase letter: append it +// - '*': remove the last character (no-op if the buffer is empty) +// - '#': duplicate the buffer (append a copy of it to itself) +// - '%': reverse the buffer in place +// The constraints are tiny (len(s) <= 20), so performing each operation +// literally is both simple and fast. +func processStr(s string) string { + result := make([]byte, 0) + + for i := 0; i < len(s); i++ { + switch c := s[i]; c { + case '*': + if len(result) > 0 { + result = result[:len(result)-1] + } + case '#': + result = append(result, result...) + case '%': + for l, r := 0, len(result)-1; l < r; l, r = l+1, r-1 { + result[l], result[r] = result[r], result[l] + } + default: + result = append(result, c) + } + } + + return string(result) +} diff --git a/problems/3612-process-string-with-special-operations-i/solution_daily_20260616_test.go b/problems/3612-process-string-with-special-operations-i/solution_daily_20260616_test.go new file mode 100644 index 0000000..da41187 --- /dev/null +++ b/problems/3612-process-string-with-special-operations-i/solution_daily_20260616_test.go @@ -0,0 +1,29 @@ +package main + +import "testing" + +func TestProcessStr(t *testing.T) { + tests := []struct { + name string + s string + expected string + }{ + {"example 1: a#b%* -> ba", "a#b%*", "ba"}, + {"example 2: z*# empties then duplicates empty", "z*#", ""}, + {"edge case: empty result on leading remove", "*abc", "abc"}, + {"edge case: only special chars stays empty", "*%#", ""}, + {"edge case: single letter", "q", "q"}, + {"edge case: duplicate then reverse palindrome-ish", "ab#", "abab"}, + {"edge case: reverse of empty is empty", "%", ""}, + {"edge case: remove all then append", "ab**c", "c"}, + {"edge case: reverse single char unchanged", "a%", "a"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := processStr(tt.s); got != tt.expected { + t.Errorf("processStr(%q) = %q, want %q", tt.s, got, tt.expected) + } + }) + } +}