68
68
69
69
<!-- solution:start -->
70
70
71
- ### 方法一
71
+ ### 方法一:贪心
72
+
73
+ 我们可以每次贪心地选取一个不超过 $k$ 的最大的斐波那契数,然后将 $k$ 减去该数,答案加一,一直循环,直到 $k = 0$ 为止。
74
+
75
+ 由于每次贪心地选取了最大的不超过 $k$ 的斐波那契数,假设为 $b$,前一个数为 $a$,后一个数为 $c$。将 $k$ 减去 $b$,得到的结果,一定小于 $a$,也即意味着,我们选取了 $b$ 之后,一定不会选到 $a$。这是因为,如果能选上 $a$,那么我们在前面就可以贪心地选上 $b$ 的下一个斐波那契数 $c$,这不符合我们的假设。因此,我们在选取 $b$ 之后,可以贪心地减小斐波那契数。
76
+
77
+ 时间复杂度 $O(\log k)$,空间复杂度 $O(1)$。
72
78
73
79
<!-- tabs:start -->
74
80
@@ -77,32 +83,40 @@ tags:
77
83
``` python
78
84
class Solution :
79
85
def findMinFibonacciNumbers (self , k : int ) -> int :
80
- def dfs (k ):
81
- if k < 2 :
82
- return k
83
- a = b = 1
84
- while b <= k:
85
- a, b = b, a + b
86
- return 1 + dfs(k - a)
87
-
88
- return dfs(k)
86
+ a = b = 1
87
+ while b <= k:
88
+ a, b = b, a + b
89
+ ans = 0
90
+ while k:
91
+ if k >= b:
92
+ k -= b
93
+ ans += 1
94
+ a, b = b - a, a
95
+ return ans
89
96
```
90
97
91
98
#### Java
92
99
93
100
``` java
94
101
class Solution {
95
-
96
102
public int findMinFibonacciNumbers (int k ) {
97
- if (k < 2 ) {
98
- return k;
99
- }
100
103
int a = 1 , b = 1 ;
101
104
while (b <= k) {
102
- b = a + b;
103
- a = b - a;
105
+ int c = a + b;
106
+ a = b;
107
+ b = c;
104
108
}
105
- return 1 + findMinFibonacciNumbers(k - a);
109
+ int ans = 0 ;
110
+ while (k > 0 ) {
111
+ if (k >= b) {
112
+ k -= b;
113
+ ++ ans;
114
+ }
115
+ int c = b - a;
116
+ b = a;
117
+ a = c;
118
+ }
119
+ return ans;
106
120
}
107
121
}
108
122
```
@@ -113,80 +127,100 @@ class Solution {
113
127
class Solution {
114
128
public:
115
129
int findMinFibonacciNumbers(int k) {
116
- if (k < 2) return k;
117
130
int a = 1, b = 1;
118
131
while (b <= k) {
119
- b = a + b;
120
- a = b - a;
132
+ int c = a + b;
133
+ a = b;
134
+ b = c;
121
135
}
122
- return 1 + findMinFibonacciNumbers(k - a);
136
+ int ans = 0;
137
+ while (k > 0) {
138
+ if (k >= b) {
139
+ k -= b;
140
+ ++ans;
141
+ }
142
+ int c = b - a;
143
+ b = a;
144
+ a = c;
145
+ }
146
+ return ans;
123
147
}
124
148
};
125
149
```
126
150
127
151
#### Go
128
152
129
153
```go
130
- func findMinFibonacciNumbers(k int) int {
131
- if k < 2 {
132
- return k
133
- }
154
+ func findMinFibonacciNumbers(k int) (ans int) {
134
155
a, b := 1, 1
135
156
for b <= k {
136
- a, b = b, a+b
157
+ c := a + b
158
+ a = b
159
+ b = c
137
160
}
138
- return 1 + findMinFibonacciNumbers(k-a)
161
+
162
+ for k > 0 {
163
+ if k >= b {
164
+ k -= b
165
+ ans++
166
+ }
167
+ c := b - a
168
+ b = a
169
+ a = c
170
+ }
171
+ return
139
172
}
140
173
```
141
174
142
175
#### TypeScript
143
176
144
177
``` ts
145
- const arr = [
146
- 1836311903 , 1134903170 , 701408733 , 433494437 , 267914296 , 165580141 , 102334155 , 63245986 ,
147
- 39088169 , 24157817 , 14930352 , 9227465 , 5702887 , 3524578 , 2178309 , 1346269 , 832040 , 514229 ,
148
- 317811 , 196418 , 121393 , 75025 , 46368 , 28657 , 17711 , 10946 , 6765 , 4181 , 2584 , 1597 , 987 , 610 ,
149
- 377 , 233 , 144 , 89 , 55 , 34 , 21 , 13 , 8 , 5 , 3 , 2 , 1 ,
150
- ];
151
-
152
178
function findMinFibonacciNumbers(k : number ): number {
153
- let res = 0 ;
154
- for (const num of arr ) {
155
- if (k >= num ) {
156
- k -= num ;
157
- res ++ ;
158
- if (k === 0 ) {
159
- break ;
160
- }
179
+ let [a, b] = [1 , 1 ];
180
+ while (b <= k ) {
181
+ let c = a + b ;
182
+ a = b ;
183
+ b = c ;
184
+ }
185
+
186
+ let ans = 0 ;
187
+ while (k > 0 ) {
188
+ if (k >= b ) {
189
+ k -= b ;
190
+ ans ++ ;
161
191
}
192
+ let c = b - a ;
193
+ b = a ;
194
+ a = c ;
162
195
}
163
- return res ;
196
+ return ans ;
164
197
}
165
198
```
166
199
167
200
#### Rust
168
201
169
202
``` rust
170
- const FIB : [i32 ; 45 ] = [
171
- 1836311903 , 1134903170 , 701408733 , 433494437 , 267914296 , 165580141 , 102334155 , 63245986 ,
172
- 39088169 , 24157817 , 14930352 , 9227465 , 5702887 , 3524578 , 2178309 , 1346269 , 832040 , 514229 ,
173
- 317811 , 196418 , 121393 , 75025 , 46368 , 28657 , 17711 , 10946 , 6765 , 4181 , 2584 , 1597 , 987 , 610 ,
174
- 377 , 233 , 144 , 89 , 55 , 34 , 21 , 13 , 8 , 5 , 3 , 2 , 1 ,
175
- ];
176
-
177
203
impl Solution {
178
204
pub fn find_min_fibonacci_numbers (mut k : i32 ) -> i32 {
179
- let mut res = 0 ;
180
- for & i in FIB . into_iter () {
181
- if k >= i {
182
- k -= i ;
183
- res += 1 ;
184
- if k == 0 {
185
- break ;
186
- }
205
+ let mut a = 1 ;
206
+ let mut b = 1 ;
207
+ while b <= k {
208
+ let c = a + b ;
209
+ a = b ;
210
+ b = c ;
211
+ }
212
+
213
+ let mut ans = 0 ;
214
+ while k > 0 {
215
+ if k >= b {
216
+ k -= b ;
217
+ ans += 1 ;
187
218
}
219
+ let c = b - a ;
220
+ b = a ;
221
+ a = c ;
188
222
}
189
- res
223
+ ans
190
224
}
191
225
}
192
226
```
0 commit comments