Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit e6631e9

Browse files
committed
964 done
1 parent 1131cca commit e6631e9

File tree

2 files changed

+30
-62
lines changed

2 files changed

+30
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,33 @@
11
package problem0964
22

3-
import (
4-
"math"
5-
)
3+
// ref: https://leetcode.com/problems/least-operators-to-express-number/discuss/208376/python2-O(log-target)-chinese
4+
5+
// 由于不能有括号,所以每一位(x进制)必须是由自己组成或者由下一位减自己余数组成,所以首先短除法求出每一位的余数
6+
// 在个位的时候,必须用x/x表示1,所以*2,但其它位不用,所以单独先提出
7+
// 正数表示时,可用自己+剩下的正数表示或者多加一个本位然后减去上一位的余数表示
8+
// 负数表示时,可用自己的余数加上剩下的正数表示或者用自己的余数+剩下的余数,但此时可以合并同级项减少运算符
9+
// 如在10进制下,86可表示为
10+
// 80 + 6 (6 为下一位正数表示
11+
// 80 + 10 - 4 (4 为下一位负数表示)
12+
// 100 - 20 + 6 (100-20为本位余数表示,6为下一位正数表示
13+
// 100 - 20 + 10 - 4 (100-20为本位余数表示,10 -4 为下一位余数表示
14+
// 在此时, 20 和 10注定为同一位且符号相反,可以省去两个符号(一个符号在该位用i 个符号表示(如100为第二位,所以表示为+10 * 10,用两个符号,在此时所有符号均带自己的正负号
15+
// 因为在前面算法中所有位都带自己的正负号,所以第一位应该减去自己的符号,所以总量减1
16+
// 或者在余数表示法中,加上一个更高位的减去自己表示本位余数
17+
// 所以此题归根结底还是考察对进制的理解而不是简单的理解bfs, dfs,那样复杂度远远高于此,但是是对惯性思维者的一种挑战
618

719
func leastOpsExpressTarget(x int, target int) int {
8-
//fmt.Println("-=-=-=-=-=-=-=-=-")
9-
res := math.MaxInt64
10-
helper(x, target, 0, &res)
11-
return res
12-
}
13-
14-
func helper(x, target, count int, res *int) {
15-
//fmt.Println(target, count)
16-
if count >= *res {
17-
return
18-
}
19-
20-
if target == x {
21-
*res = min(*res, count)
22-
//fmt.Println("-", *res)
23-
return
24-
} else if target < x {
25-
*res = min(
26-
*res,
27-
count+min(
28-
target*2-1,
29-
1+(x-target)*2-1,
30-
),
31-
)
32-
//fmt.Println("-", *res)
33-
return
34-
}
35-
36-
root := math.Log10(float64(target)) / math.Log10(float64(x))
37-
base := int(math.Pow(float64(x), math.Floor(root)))
38-
intRoot := int(math.Floor(root))
39-
40-
if base == target {
41-
*res = min(*res, count+intRoot-1)
42-
//fmt.Println("-", *res)
43-
return
44-
} else if base*x == target {
45-
*res = min(*res, count+intRoot)
46-
//fmt.Println("-", *res)
47-
return
48-
}
49-
50-
intRoot = max(intRoot, 1)
51-
helper(x, target-base, count+intRoot, res)
52-
if base*x-target < target {
53-
helper(x, base*x-target, count+intRoot+1, res)
20+
target, r := target/x, target%x
21+
pos, neg := r*2, (x-r)*2 // 处理各位上的数
22+
23+
bit := 1
24+
for target > 0 {
25+
target, r = target/x, target%x
26+
pos, neg = min(r*bit+pos, (r+1)*bit+neg), min((x-r)*bit+pos, (x-r-1)*bit+neg)
27+
bit++
5428
}
55-
}
5629

57-
func max(a, b int) int {
58-
if a > b {
59-
return a
60-
}
61-
return b
30+
return min(pos, bit+neg) - 1
6231
}
6332

6433
func min(a, b int) int {
@@ -67,10 +36,3 @@ func min(a, b int) int {
6736
}
6837
return b
6938
}
70-
71-
func abs(x int) int {
72-
if x < 0 {
73-
return -x
74-
}
75-
return x
76-
}

Algorithms/0964.least-operators-to-express-number/least-operators-to-express-number_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ var tcs = []struct {
1313
ans int
1414
}{
1515

16+
{
17+
3,
18+
6,
19+
1,
20+
},
21+
1622
{
1723
3,
1824
55125018,

0 commit comments

Comments
 (0)