|
1 | 1 | ## Explanation |
2 | 2 |
|
3 | | -### Strategy (The "Why") |
| 3 | +### Strategy |
4 | 4 |
|
5 | | -**1.1 Constraints & Complexity:** |
| 5 | +**1.1 Constraints & Complexity** |
6 | 6 |
|
7 | | -- **Constraints:** $1 \leq n \leq 1000$ where $n$ is the string length. String contains only lowercase English letters. |
8 | | -- **Time Complexity:** $O(n^2)$ where $n$ is the string length. We try $2n$ operations, each involving string reversal which is $O(n)$. |
9 | | -- **Space Complexity:** $O(n)$ for storing reversed strings. |
10 | | -- **Edge Case:** If the string is already lexicographically smallest, return it unchanged. |
| 7 | + * **Input Size:** The string `s` has length `n` where `1 <= n <= 1000`. This is a small constraint that allows for a straightforward approach. |
| 8 | + * **Time Complexity:** O(n^2) - We try all possible values of `k` from 1 to `n` for both prefix and suffix reversals, and each reversal operation takes O(n) time. |
| 9 | + * **Space Complexity:** O(n) - We create new string candidates for comparison, but we only keep the best one at any time. |
| 10 | + * **Edge Case:** If no reversal produces a lexicographically smaller string, we return the original string. |
11 | 11 |
|
12 | | -**1.2 High-level approach:** |
| 12 | +**1.2 High-level approach** |
13 | 13 |
|
14 | | -The goal is to find the lexicographically smallest string after performing exactly one operation: either reversing the first $k$ characters or the last $k$ characters for some $k$. We try all possible operations and return the lexicographically smallest result. |
| 14 | +The goal is to find the lexicographically smallest string achievable by performing exactly one reversal operation (either on the first `k` characters or the last `k` characters). |
15 | 15 |
|
16 | | -**1.3 Brute force vs. optimized strategy:** |
| 16 | +Imagine you have a string written on cards. You can flip either the leftmost `k` cards or the rightmost `k` cards exactly once, and you want the resulting arrangement to be as small as possible when read left to right. |
17 | 17 |
|
18 | | -- **Brute Force:** Try all $2n$ possible operations (reverse first $k$ for $k=1$ to $n$, reverse last $k$ for $k=1$ to $n$), compare results. This is $O(n^2)$ time. |
19 | | -- **Optimized Strategy:** Same as brute force - we need to check all possibilities since there's no obvious pattern to skip. This is $O(n^2)$ time. |
20 | | -- **Why this approach:** The problem constraints allow $O(n^2)$ solution, and there's no obvious optimization to avoid checking all operations. |
| 18 | +**1.3 Brute force vs. optimized strategy** |
21 | 19 |
|
22 | | -**1.4 Decomposition:** |
| 20 | + * **Brute Force:** Try all possible values of `k` from 1 to `n` for prefix reversals, and all possible values of `k` from 1 to `n` for suffix reversals. For each candidate, compare it lexicographically with the current best result. This is exactly what we do, and it's efficient enough given the small constraint. |
| 21 | + * **Optimized Strategy:** The brute force approach is already optimal for this problem size. We systematically check all `2n` possible operations (n prefix reversals + n suffix reversals) and keep track of the lexicographically smallest result. |
23 | 22 |
|
24 | | -1. Initialize result as the original string. |
25 | | -2. Try reversing first $k$ characters for $k = 1$ to $n$: |
26 | | - - Reverse `s[:k]` and concatenate with `s[k:]` |
27 | | - - Update result if this is lexicographically smaller. |
28 | | -3. Try reversing last $k$ characters for $k = 1$ to $n$: |
29 | | - - Keep `s[:n-k]` and reverse `s[n-k:]` |
30 | | - - Update result if this is lexicographically smaller. |
31 | | -4. Return the result. |
| 23 | +**1.4 Decomposition** |
32 | 24 |
|
33 | | -### Steps (The "How") |
| 25 | +1. Initialize the result with the original string as the baseline. |
| 26 | +2. Try all prefix reversals: For each `k` from 1 to `n`, reverse the first `k` characters and compare the result. |
| 27 | +3. Try all suffix reversals: For each `k` from 1 to `n`, reverse the last `k` characters and compare the result. |
| 28 | +4. Update the result whenever we find a lexicographically smaller candidate. |
| 29 | +5. Return the smallest string found. |
34 | 30 |
|
35 | | -**2.1 Initialization & Example Setup:** |
| 31 | +### Steps |
36 | 32 |
|
37 | | -Let's use the example: `s = "dcab"` |
| 33 | +**2.1 Initialization & Example Setup** |
38 | 34 |
|
39 | | -We initialize `res = "dcab"`. |
| 35 | +Let's use the example `s = "dcab"` to trace through the solution. |
40 | 36 |
|
41 | | -**2.2 Start Checking:** |
| 37 | +We initialize `res = "dcab"` as our current best result. |
42 | 38 |
|
43 | | -We try all possible reversal operations. |
| 39 | +**2.2 Start Checking/Processing** |
44 | 40 |
|
45 | | -**2.3 Trace Walkthrough:** |
| 41 | +We begin by trying all possible prefix reversals (reversing the first `k` characters) for `k` from 1 to `n`. |
46 | 42 |
|
47 | | -**Reverse first k characters:** |
48 | | -- k=1: "d" + "cab" = "dcab" (not smaller) |
49 | | -- k=2: "cd" + "ab" = "cdab" (not smaller) |
50 | | -- k=3: "acd" + "b" = "acdb" (smaller! update res) |
51 | | -- k=4: "bacd" (not smaller) |
| 43 | +**2.3 Trace Walkthrough** |
52 | 44 |
|
53 | | -**Reverse last k characters:** |
54 | | -- k=1: "dca" + "b" = "dcab" (not smaller) |
55 | | -- k=2: "dc" + "ba" = "dcba" (not smaller) |
56 | | -- k=3: "d" + "bac" = "dbac" (not smaller) |
57 | | -- k=4: "bacd" (not smaller) |
| 45 | +| k | Prefix to Reverse | Reversed Prefix | Remaining | Candidate | Is Smaller? | Update res? | |
| 46 | +|---|-------------------|-----------------|-----------|-----------|-------------|--------------| |
| 47 | +| 1 | "d" | "d" | "cab" | "dcab" | No | No | |
| 48 | +| 2 | "dc" | "cd" | "ab" | "cdab" | No | No | |
| 49 | +| 3 | "dca" | "acd" | "b" | "acdb" | Yes | Yes → "acdb" | |
| 50 | +| 4 | "dcab" | "bacd" | "" | "bacd" | No | No | |
58 | 51 |
|
59 | | -Best result: "acdb" |
| 52 | +Now we try suffix reversals (reversing the last `k` characters): |
60 | 53 |
|
61 | | -**2.4 Increment and Loop:** |
| 54 | +| k | Suffix to Reverse | Remaining | Reversed Suffix | Candidate | Is Smaller? | Update res? | |
| 55 | +|---|-------------------|-----------|-----------------|-----------|-------------|--------------| |
| 56 | +| 1 | "b" | "dca" | "b" | "dcab" | No | No | |
| 57 | +| 2 | "ab" | "dc" | "ba" | "dcba" | No | No | |
| 58 | +| 3 | "cab" | "d" | "bac" | "dbac" | No | No | |
| 59 | +| 4 | "dcab" | "" | "bacd" | "bacd" | No | No | |
62 | 60 |
|
63 | | -- For $k$ from 1 to $n$: |
64 | | - - `reversed_str = s[:k][::-1] + s[k:]` |
65 | | - - `if reversed_str < res: res = reversed_str` |
66 | | -- For $k$ from 1 to $n$: |
67 | | - - `reversed_str = s[:n-k] + s[n-k:][::-1]` |
68 | | - - `if reversed_str < res: res = reversed_str` |
| 61 | +**2.4 Increment and Loop** |
69 | 62 |
|
70 | | -**2.5 Return Result:** |
| 63 | +After checking all prefix reversals, we move to checking all suffix reversals. We continue until we've examined all `2n` possible operations. |
71 | 64 |
|
72 | | -For `s = "dcab"`, the lexicographically smallest result is "acdb" (obtained by reversing the first 3 characters). We return "acdb". |
| 65 | +**2.5 Return Result** |
73 | 66 |
|
| 67 | +The lexicographically smallest string found is `"acdb"`, which we return as the final result. |
0 commit comments