1
1
package problem0964
2
2
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,那样复杂度远远高于此,但是是对惯性思维者的一种挑战
6
18
7
19
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 ++
54
28
}
55
- }
56
29
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
62
31
}
63
32
64
33
func min (a , b int ) int {
@@ -67,10 +36,3 @@ func min(a, b int) int {
67
36
}
68
37
return b
69
38
}
70
-
71
- func abs (x int ) int {
72
- if x < 0 {
73
- return - x
74
- }
75
- return x
76
- }
0 commit comments