Skip to content

Commit

Permalink
feat: add ts solution to lc problem: No.0514 (#2273)
Browse files Browse the repository at this point in the history
No.0514.Freedom Trail
  • Loading branch information
yanglbme authored Jan 29, 2024
1 parent e3f7ac0 commit ff3350d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
34 changes: 34 additions & 0 deletions solution/0500-0599/0514.Freedom Trail/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,40 @@ func abs(x int) int {
}
```

```ts
function findRotateSteps(ring: string, key: string): number {
const m: number = key.length;
const n: number = ring.length;
const pos: number[][] = Array.from({ length: 26 }, () => []);
for (let i = 0; i < n; ++i) {
const j: number = ring.charCodeAt(i) - 'a'.charCodeAt(0);
pos[j].push(i);
}

const f: number[][] = Array.from({ length: m }, () => Array(n).fill(1 << 30));
for (const j of pos[key.charCodeAt(0) - 'a'.charCodeAt(0)]) {
f[0][j] = Math.min(j, n - j) + 1;
}

for (let i = 1; i < m; ++i) {
for (const j of pos[key.charCodeAt(i) - 'a'.charCodeAt(0)]) {
for (const k of pos[key.charCodeAt(i - 1) - 'a'.charCodeAt(0)]) {
f[i][j] = Math.min(
f[i][j],
f[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1,
);
}
}
}

let ans: number = 1 << 30;
for (const j of pos[key.charCodeAt(m - 1) - 'a'.charCodeAt(0)]) {
ans = Math.min(ans, f[m - 1][j]);
}
return ans;
}
```

<!-- tabs:end -->

<!-- end -->
48 changes: 47 additions & 1 deletion solution/0500-0599/0514.Freedom Trail/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,19 @@ So the final output is 4.

## Solutions

### Solution 1
### Solution 1: Dynamic Programming

First, we preprocess the positions of each character $c$ in the string $ring$, and record them in the array $pos[c]$. Suppose the lengths of the strings $key$ and $ring$ are $m$ and $n$, respectively.

Then we define $f[i][j]$ as the minimum number of steps to spell the first $i+1$ characters of the string $key$, and the $j$-th character of $ring$ is aligned with the $12:00$ direction. Initially, $f[i][j]=+\infty$. The answer is $\min_{0 \leq j < n} f[m - 1][j]$.

We can first initialize $f[0][j]$, where $j$ is the position where the character $key[0]$ appears in $ring$. Since the $j$-th character of $ring$ is aligned with the $12:00$ direction, we only need $1$ step to spell $key[0]$. In addition, we need $min(j, n - j)$ steps to rotate $ring$ to the $12:00$ direction. Therefore, $f[0][j]=min(j, n - j) + 1$.

Next, we consider how the state transitions when $i \geq 1$. We can enumerate the position list $pos[key[i]]$ where $key[i]$ appears in $ring$, and enumerate the position list $pos[key[i-1]]$ where $key[i-1]$ appears in $ring$, and then update $f[i][j]$, i.e., $f[i][j]=\min_{k \in pos[key[i-1]]} f[i-1][k] + \min(\text{abs}(j - k), n - \text{abs}(j - k)) + 1$.

Finally, we return $\min_{0 \leq j \lt n} f[m - 1][j]$.

The time complexity is $O(m \times n^2)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the lengths of the strings $key$ and $ring$, respectively.

<!-- tabs:start -->

Expand Down Expand Up @@ -174,6 +186,40 @@ func abs(x int) int {
}
```

```ts
function findRotateSteps(ring: string, key: string): number {
const m: number = key.length;
const n: number = ring.length;
const pos: number[][] = Array.from({ length: 26 }, () => []);
for (let i = 0; i < n; ++i) {
const j: number = ring.charCodeAt(i) - 'a'.charCodeAt(0);
pos[j].push(i);
}

const f: number[][] = Array.from({ length: m }, () => Array(n).fill(1 << 30));
for (const j of pos[key.charCodeAt(0) - 'a'.charCodeAt(0)]) {
f[0][j] = Math.min(j, n - j) + 1;
}

for (let i = 1; i < m; ++i) {
for (const j of pos[key.charCodeAt(i) - 'a'.charCodeAt(0)]) {
for (const k of pos[key.charCodeAt(i - 1) - 'a'.charCodeAt(0)]) {
f[i][j] = Math.min(
f[i][j],
f[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1,
);
}
}
}

let ans: number = 1 << 30;
for (const j of pos[key.charCodeAt(m - 1) - 'a'.charCodeAt(0)]) {
ans = Math.min(ans, f[m - 1][j]);
}
return ans;
}
```

<!-- tabs:end -->

<!-- end -->
31 changes: 31 additions & 0 deletions solution/0500-0599/0514.Freedom Trail/Solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
function findRotateSteps(ring: string, key: string): number {
const m: number = key.length;
const n: number = ring.length;
const pos: number[][] = Array.from({ length: 26 }, () => []);
for (let i = 0; i < n; ++i) {
const j: number = ring.charCodeAt(i) - 'a'.charCodeAt(0);
pos[j].push(i);
}

const f: number[][] = Array.from({ length: m }, () => Array(n).fill(1 << 30));
for (const j of pos[key.charCodeAt(0) - 'a'.charCodeAt(0)]) {
f[0][j] = Math.min(j, n - j) + 1;
}

for (let i = 1; i < m; ++i) {
for (const j of pos[key.charCodeAt(i) - 'a'.charCodeAt(0)]) {
for (const k of pos[key.charCodeAt(i - 1) - 'a'.charCodeAt(0)]) {
f[i][j] = Math.min(
f[i][j],
f[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1,
);
}
}
}

let ans: number = 1 << 30;
for (const j of pos[key.charCodeAt(m - 1) - 'a'.charCodeAt(0)]) {
ans = Math.min(ans, f[m - 1][j]);
}
return ans;
}

0 comments on commit ff3350d

Please sign in to comment.