mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-05 00:25:22 +08:00
规范格式
This commit is contained in:
39
leetcode/0753.Cracking-the-Safe/753. Cracking the Safe.go
Normal file
39
leetcode/0753.Cracking-the-Safe/753. Cracking the Safe.go
Normal file
@ -0,0 +1,39 @@
|
||||
package leetcode
|
||||
|
||||
import "math"
|
||||
|
||||
const number = "0123456789"
|
||||
|
||||
func crackSafe(n int, k int) string {
|
||||
if n == 1 {
|
||||
return number[:k]
|
||||
}
|
||||
visit, total := map[string]bool{}, int(math.Pow(float64(k), float64(n)))
|
||||
str := make([]byte, 0, total+n-1)
|
||||
for i := 1; i != n; i++ {
|
||||
str = append(str, '0')
|
||||
}
|
||||
dfsCrackSafe(total, n, k, &str, &visit)
|
||||
return string(str)
|
||||
}
|
||||
|
||||
func dfsCrackSafe(depth, n, k int, str *[]byte, visit *map[string]bool) bool {
|
||||
if depth == 0 {
|
||||
return true
|
||||
}
|
||||
for i := 0; i != k; i++ {
|
||||
*str = append(*str, byte('0'+i))
|
||||
cur := string((*str)[len(*str)-n:])
|
||||
if _, ok := (*visit)[cur]; ok != true {
|
||||
(*visit)[cur] = true
|
||||
if dfsCrackSafe(depth-1, n, k, str, visit) {
|
||||
// 只有这里不需要删除
|
||||
return true
|
||||
}
|
||||
delete(*visit, cur)
|
||||
}
|
||||
// 删除
|
||||
*str = (*str)[0 : len(*str)-1]
|
||||
}
|
||||
return false
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question753 struct {
|
||||
para753
|
||||
ans753
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para753 struct {
|
||||
n int
|
||||
k int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans753 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
func Test_Problem753(t *testing.T) {
|
||||
|
||||
qs := []question753{
|
||||
|
||||
question753{
|
||||
para753{1, 2},
|
||||
ans753{"01"},
|
||||
},
|
||||
|
||||
question753{
|
||||
para753{2, 2},
|
||||
ans753{"00110"},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 753------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans753, q.para753
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, crackSafe(p.n, p.k))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
91
leetcode/0753.Cracking-the-Safe/README.md
Normal file
91
leetcode/0753.Cracking-the-Safe/README.md
Normal file
@ -0,0 +1,91 @@
|
||||
# 753. Cracking the Safe
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
There is a box protected by a password. The password is a sequence of `n` digits where each digit can be one of the first `k` digits `0, 1, ..., k-1`.
|
||||
|
||||
While entering a password, the last `n` digits entered will automatically be matched against the correct password.
|
||||
|
||||
For example, assuming the correct password is `"345"`, if you type `"012345"`, the box will open because the correct password matches the suffix of the entered password.
|
||||
|
||||
Return any password of **minimum length** that is guaranteed to open the box at some point of entering it.
|
||||
|
||||
**Example 1**:
|
||||
|
||||
```
|
||||
Input: n = 1, k = 2
|
||||
Output: "01"
|
||||
Note: "10" will be accepted too.
|
||||
```
|
||||
|
||||
**Example 2**:
|
||||
|
||||
```
|
||||
Input: n = 2, k = 2
|
||||
Output: "00110"
|
||||
Note: "01100", "10011", "11001" will be accepted too.
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
1. `n` will be in the range `[1, 4]`.
|
||||
2. `k` will be in the range `[1, 10]`.
|
||||
3. `k^n` will be at most `4096`.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
有一个需要密码才能打开的保险箱。密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 。你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保险箱。举个例子,假设密码是 "345",你可以输入 "012345" 来打开它,只是你输入了 6 个字符.请返回一个能打开保险箱的最短字符串。
|
||||
|
||||
提示:
|
||||
|
||||
- n 的范围是 [1, 4]。
|
||||
- k 的范围是 [1, 10]。
|
||||
- k^n 最大可能为 4096。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出 2 个数字 n 和 k,n 代表密码是 n 位数,k 代表密码是 k 位。保险箱会记住最后 n 位输入。返回一个能打开保险箱的最短字符串。
|
||||
- 看到题目中的数据范围,数据范围很小,所以可以考虑用 DFS。想解开保险箱,当然是暴力破解,枚举所有可能。题目要求我们输出一个最短的字符串,这里是本题的关键,为何有最短呢?这里有贪心的思想。如果下一次递归可以利用上一次的 n-1 位,那么最终输出的字符串肯定是最短的。(笔者这里就不证明了),例如,例子 2 中,最短的字符串是 00,01,11,10。每次尝试都利用前一次的 n-1 位。想通了这个问题,利用 DFS 暴力回溯即可。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
const number = "0123456789"
|
||||
|
||||
func crackSafe(n int, k int) string {
|
||||
if n == 1 {
|
||||
return number[:k]
|
||||
}
|
||||
visit, total := map[string]bool{}, int(math.Pow(float64(k), float64(n)))
|
||||
str := make([]byte, 0, total+n-1)
|
||||
for i := 1; i != n; i++ {
|
||||
str = append(str, '0')
|
||||
}
|
||||
dfsCrackSafe(total, n, k, &str, &visit)
|
||||
return string(str)
|
||||
}
|
||||
|
||||
func dfsCrackSafe(depth, n, k int, str *[]byte, visit *map[string]bool) bool {
|
||||
if depth == 0 {
|
||||
return true
|
||||
}
|
||||
for i := 0; i != k; i++ {
|
||||
*str = append(*str, byte('0'+i))
|
||||
cur := string((*str)[len(*str)-n:])
|
||||
if _, ok := (*visit)[cur]; ok != true {
|
||||
(*visit)[cur] = true
|
||||
if dfsCrackSafe(depth-1, n, k, str, visit) {
|
||||
// 只有这里不需要删除
|
||||
return true
|
||||
}
|
||||
delete(*visit, cur)
|
||||
}
|
||||
// 删除
|
||||
*str = (*str)[0 : len(*str)-1]
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user