6868
6969<!-- solution:start -->
7070
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)$。
7278
7379<!-- tabs:start -->
7480
@@ -77,32 +83,40 @@ tags:
7783``` python
7884class Solution :
7985 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
8996```
9097
9198#### Java
9299
93100``` java
94101class Solution {
95-
96102 public int findMinFibonacciNumbers (int k ) {
97- if (k < 2 ) {
98- return k;
99- }
100103 int a = 1 , b = 1 ;
101104 while (b <= k) {
102- b = a + b;
103- a = b - a;
105+ int c = a + b;
106+ a = b;
107+ b = c;
104108 }
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;
106120 }
107121}
108122```
@@ -113,80 +127,100 @@ class Solution {
113127class Solution {
114128public:
115129 int findMinFibonacciNumbers(int k) {
116- if (k < 2) return k;
117130 int a = 1, b = 1;
118131 while (b <= k) {
119- b = a + b;
120- a = b - a;
132+ int c = a + b;
133+ a = b;
134+ b = c;
121135 }
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;
123147 }
124148};
125149```
126150
127151#### Go
128152
129153```go
130- func findMinFibonacciNumbers(k int) int {
131- if k < 2 {
132- return k
133- }
154+ func findMinFibonacciNumbers(k int) (ans int) {
134155 a, b := 1, 1
135156 for b <= k {
136- a, b = b, a+b
157+ c := a + b
158+ a = b
159+ b = c
137160 }
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
139172}
140173```
141174
142175#### TypeScript
143176
144177``` 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-
152178function 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 ++ ;
161191 }
192+ let c = b - a ;
193+ b = a ;
194+ a = c ;
162195 }
163- return res ;
196+ return ans ;
164197}
165198```
166199
167200#### Rust
168201
169202``` 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-
177203impl Solution {
178204 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 ;
187218 }
219+ let c = b - a ;
220+ b = a ;
221+ a = c ;
188222 }
189- res
223+ ans
190224 }
191225}
192226```
0 commit comments