Skip to content

Commit

Permalink
Merge pull request #854 from 0xff-dev/752
Browse files Browse the repository at this point in the history
Add solution and test-cases for problem 752
  • Loading branch information
6boris authored Jun 6, 2024
2 parents 66aca24 + 155aa22 commit ec47cff
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 25 deletions.
38 changes: 25 additions & 13 deletions leetcode/701-800/0752.Open-the-Lock/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
# [752.Open the Lock][title]

> [!WARNING|style:flat]
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
## Description
You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: `'0'`, `'1'`, `'2'`, `'3'`, `'4'`, `'5'`, `'6'`, `'7'`, `'8'`, `'9'`. The wheels can rotate freely and wrap around: for example we can turn `'9'` to be `'0'`, or `'0'` to be `'9'`. Each move consists of turning one wheel one slot.

The lock initially starts at `'0000'`, a string representing the state of the 4 wheels.

You are given a list of `deadends` dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.

Given a `target` representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.

**Example 1:**

```
Input: a = "11", b = "1"
Output: "100"
Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6
Explanation:
A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end "0102".
```

## 题意
> ...
## 题解
**Example 2:**

### 思路1
> ...
Open the Lock
```go
```
Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation: We can turn the last wheel in reverse to move from "0000" -> "0009".
```

**Example 3:**

```
Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
Output: -1
Explanation: We cannot reach the target without getting stuck.
```

## 结语

Expand Down
68 changes: 66 additions & 2 deletions leetcode/701-800/0752.Open-the-Lock/Solution.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
package Solution

func Solution(x bool) bool {
return x
type state752 struct {
cur [4]byte
cnt int
}

// "0201","0101","0102","1212","2002"
// 0202
// 0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
func Solution(deadends []string, target string) int {
dm := make(map[[4]byte]struct{})
for _, d := range deadends {
x := [4]byte{}
for i := 0; i < 4; i++ {
x[i] = d[i]
}
dm[x] = struct{}{}
}
var (
add func(byte) byte
del func(byte) byte
)
add = func(a byte) byte {
if a == '9' {
return '0'
}
return a + 1
}
del = func(a byte) byte {
if a == '0' {
return '9'
}
return a - 1
}

state := [4]byte{target[0], target[1], target[2], target[3]}
queue := []state752{{state, 0}}
used := make(map[[4]byte]struct{})
used[state] = struct{}{}
for len(queue) > 0 {
nq := make([]state752, 0)
for _, cur := range queue {
if _, ok := dm[cur.cur]; ok {
continue
}
if cur.cur[0] == '0' && cur.cur[1] == '0' && cur.cur[2] == '0' && cur.cur[3] == '0' {
return cur.cnt
}

for i := 0; i < 4; i++ {
ss := cur.cur[i]
source := cur.cur
source[i] = add(ss)
if _, ok := used[source]; !ok {
used[source] = struct{}{}
nq = append(nq, state752{cur: source, cnt: cur.cnt + 1})
}
source[i] = del(ss)
if _, ok := used[source]; !ok {
used[source] = struct{}{}
nq = append(nq, state752{cur: source, cnt: cur.cnt + 1})
}
}
}
queue = nq
}
return -1
}
21 changes: 11 additions & 10 deletions leetcode/701-800/0752.Open-the-Lock/Solution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,31 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
inputs []string
target string
expect int
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", []string{"0201", "0101", "0102", "1212", "2002"}, "0202", 6},
{"TestCase2", []string{"8888"}, "0009", 1},
{"TestCase3", []string{"8887", "8889", "8878", "8898", "8788", "8988", "7888", "9888"}, "8888", -1},
}

// 开始测试
for i, c := range cases {
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
got := Solution(c.inputs)
got := Solution(c.inputs, c.target)
if !reflect.DeepEqual(got, c.expect) {
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
c.expect, got, c.inputs)
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v",
c.expect, got, c.inputs, c.target)
}
})
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}

0 comments on commit ec47cff

Please sign in to comment.