( l: D: i2 a0 O( p" D. ^* P0 ?4 O) x//用一个HashMap来保存已经计算过的状态 5 I$ R* t, ]' t- Zstatic Map<Integer,Integer> map = new HashMap();: a& D5 u7 n1 K) ^! c; h+ `
public static int solve(int n){. s9 r! |( v+ S# M
if(n <= 2){# r! D2 o8 t- a% X
return n;; |& l) R/ f0 ~5 y9 }/ ]
}else{//是否计算过$ c, G/ U3 s" }$ C% i& ^3 S
if(map.containsKey(n)){, G6 v* j9 v/ ^! \+ K2 _
return map.get(n); 5 d' W7 P' w7 _* n, X1 Y- m }else{ ' T' O$ A% ?' S% L; b; a int m = solve(n-1) + solve(n-2);+ K3 V0 R, m5 b; X; @/ t. G( o4 w
map.put(n, m);) v1 E4 c6 D1 Y
return m; 5 P# L8 l+ K+ V+ H }0 [+ P$ T5 s8 c, S9 z
} % C8 m# U0 c( s; o}$ l+ y( r v- {- g2 n b3 j+ b
4 c/ W& `9 W! b. j4 y1 8 k3 J% n# F k' E2* h: R9 n7 S' k' e! K5 T3 W0 u% k* ]# P) I
3 $ l8 @8 K( h5 q$ D* [2 K" ~+ A48 [+ G J5 e% v: M- r6 h/ a
5$ [+ X8 E, j7 D3 |0 u
6 + ?8 P B7 ^1 n4 {. Z# c c7 % f0 p! y$ ]- l, g7 i( a$ p- W7 s89 ]& D0 m3 x" r$ p. K& T
96 }& a- E* x" R
10 ) A2 X1 Z0 w: j5 j# c8 U5 E11! ?. B8 e. g, ^
12" `8 ~$ N- D' |; c% E3 _
13 . y* K. Q5 w: I! e8 H143 F" {3 }3 V1 m! d# J
15% _( _, V3 p ?: O$ \
16/ G" {0 [3 S+ E( a
这样,可以大大缩短时间。也就是说,当一道题你做了之后,发现时间复杂度很高,那么可以考虑下,是否有更好的方法,是否可以用空间换时间。 . U# {1 u8 f4 m9 a) c. O# x; A3 D, t# F3 ~! z( @, H# K/ W
方法三:斐波那契数列 7 o' ^; ]4 x9 {0 ^! c. h) d, q5 E! m0 n7 W! i3 W0 G3 h
实际上,我们可以把空间复杂度弄的更小,不需要HashMap来保存状态: ! ?2 e/ I( x6 |1 |% j 0 L4 v- z9 @1 F+ W6 H( P4 n3 opublic static int solve(int n){1 K8 d8 J* ~2 W* g% P! T" ]
if(n <= 2){: o3 G e- K! y: H% {6 y
return n;1 _9 U% n* j9 @, h Q
} 3 ~. S T! D/ y- H% t/ h- ^ int f1 = 0;/ \( v, M3 ~- t5 `+ P
int f2 = 1; " l, Q2 ^$ M, u9 J. I int sum = 0; , s2 q7 @: n j& X3 | for(int i = 1; i<= n; i++){ ! S% @$ }' P' r) w0 ?0 D% d sum = f1 + f2;3 ?% Z# B4 V( d/ Y+ y; h2 C
f1 = f2; 0 M* w3 W' J$ I9 P# r1 w) u: k f2 = sum; ; {+ V5 _/ [+ r } ; G, h: \/ i) m, y% Q. E( ` return sum; " n$ Q) `, I' \% v6 Y: p} / E: z, x$ }; x1 # ]% z; R7 U4 R/ C; H2 5 A( c! G+ }/ T4 s0 P, f# m( R6 `37 n: F5 ~: r4 T4 e
4 " L9 N3 f! G( Q1 z+ E5 . x# p' g6 k* A- e3 b' ?6- e( L# V7 q( _: y
7! D. O- u; P) q3 u
8' _# V6 S* J) K* Q
9 1 |0 o9 i% d/ b2 v% q10 9 y0 S1 U' e$ G# F6 \. x11 . s9 o* f' l7 f8 w' s12 ' u: K; g4 u- D: k" ~: I: H' h13 $ F, U9 D! ?# R+ U3 n14, K5 @ k, r% G9 f/ m; N, r: A
我弄这道题给你们看,并不是在教你们这道题怎么做,而是有以下目的: . x# x x' N0 }7 ?4 ~7 p 4 p+ M/ Q5 |: q! J1、在刷题的时候,我们要力求完美。 ) i) \/ X) r$ i1 h3 x# c. d & d$ {) A6 d+ ^& l) i: n" c0 `, i3 p0 l2、我想不到这些方法啊,怎么办?那么你就可以去看别人的做法,之后,遇到类似的题,你就会更有思路,更知道往哪个方向想。 ( P* X9 } J ] C) O9 Q* M9 U" c, a. ^+ g3、可以从简单暴力入手做一道题,在考虑空间与时间之间的衡量,一点点去优化。 , C$ j7 k5 P7 k$ Z Q% U. ^2 @ 1 [, x. D( G- s$ {: ?" q挑战自己,跳出舒适区 d! c5 K5 L9 M$ } 2 C/ d) ^: H( u* b什么叫舒适区?在刷题的时候,可能有一类题是你比较懂的,你每次一看就有思路,然后半个小时就撸好代码,提交代码,然后通过了,然后,哇,又多刷了一道题,心里很舒服。# y' i9 l% C0 @4 I2 O- u9 m
! U4 G( y/ E( s但是,记住,前期你可以多刷这种题练手,提升自己的乐趣,但,我还是建议你慢慢跳出舒适区,去做一些自己不擅长的题,并且找段时间一直刷这种题。例如,我觉得我在递归方面的题还是挺强的, 6 l7 C6 F8 i. k5 u但是,我对动态规划的题,很菜,每次都要想好久,每次遇到这种题都有点害怕,没什么信心。不过有段时间我觉得只刷动态规划的题,直接在 leetcode 选定专题,连续做了四五十道,刚开始很难受,后来就慢慢知道了套路了,一道题从两三个小时最后缩到半小时,简单的十几分钟就搞定。感觉自己对这类型的题也不惧怕的。' O3 X2 x! O6 a0 P" b' X
: m- h6 w7 `& ~& f
当然,对于动态规划的学习,大家也可以看我这篇广受好评的文章:为什么你学不过动态规划?告别动态规划,谈谈我的经验 ( b n6 I4 E, q7 A( [4 E) J : Z0 e* c; A7 U1 \! n; i所以,建议你,一定要学好跳出自己的舒适区。 3 S$ T' ]$ w2 T" L. l) ?- n* P) i' w; l
一定要学会分类总结 9 x0 W4 T- A" [: Z5 y2 S _4 n# D4 ?( j m7 ]7 O
有些人以为 leetcode 的题刷的越多,就一定能越厉害,其实不然,leetcode 虽然有 1000 多道题,但题型就那么几类,我们前期在刷的时候,我是建议按照题型分类刷题的,例如我这整理刷二叉树相关,然后刷链表相关,然后二分法,然后递归等等,每刷一种题型,都要研究他们的套路,如果你愿意去总结,那么 leetcode 的题,其实你刷几百道,有目的、挑选的刷,我觉得就差不多了。8 f/ H+ J6 Y( u+ b2 v
" K6 h- t- s. I0 Z; d
我看过一本书,叫做《程序员代码面试指南:IT 名企算法与数据结构题目最优解》,这本书就非常不错,里面按照栈,队列,链表,二叉树,字符串等一个专题一个专题来刷的,并且每道题都给出了最优解,而且里面的题有一定的难度,感兴趣的,真心不错,如果你把这本书的题全部搞定,并且总结相关套路,那么你的算法一定有很大的提升。 7 \: ^6 a6 Z! | [' N , m1 Z& W0 Y; i8 q4 ~4 y9 l推荐一些刷题网站 ; g% n* Z" s" n* }- r/ ^& u- L. J4 t! |+ P, `5 U2 e$ V
我一般是在leetcode和牛客网刷题,感觉挺不错,题目难度不是很大。 3 m, M, C0 B f0 w" I @ ) ]$ b% p( @! ?在牛客网那里,我主要刷剑指Offer,不过那里也有个在线刷leetcode,不过里面的题量比较少。牛客网刷题有个非常方便的地方就是有个讨论区,那里会有很多大佬分享他们的解题方法,不用我们去百度找题解。所以你做完后,实在想不出,可以很方便着去看别人是怎么做的。 7 Z2 q7 S; o) q0 J c6 [7 E% @, @. {
至于leetcode,也是大部分题目官方都有给出答案,也是个不错的刷题网站。你们可以两个挑选一个,或者两个都刷。 ) }8 A5 o, @1 K! W" s( J0 V3 k/ N, O, X# v: R2 o
当然,还有其他刷题的网站,不过,其他网站没刷过,不大清除如何。 d* G( J: r6 p6 k: o1 A7 Q+ Q( t) |$ m' n n5 E+ d2 L" ^
至于leetcode,有中文版和英文版 3 n$ G2 q5 @8 c4 D1 D8 G3 r6 {" M- U8 d `
leetcode有中文版 5 Q" z' X( B: i: B- z; `/ M* p' A h J ?
英文版) a- p' W6 N7 _( c1 Y
0 [ Q$ l7 B/ ^, W: \根据自己的兴趣选。3 A& t, ~7 O4 V
' U2 V. N5 Y# L2 G. q, ^ \学习一些解题技巧& b# E- Q. U- B0 o6 p' Q, Q
3 \& s* a! d: V, ~说实话,有些题在你没看别人的解法前,你好不知道有这么美妙优雅的解法,看了之后,卧槽,居然还可以这样。而我们在刷题的过程中,就要不断累积这些技巧,当你累计多了,你就会形成一种 6 r+ S; O" e) r) H, H2 [神经反应,一下子就想到了某种方法。解题技巧很多,例如数组下标法、位图法、双指针等等,我自己也分享过一篇总结一些算法技巧的文章4 l5 G- Y- l" w9 ]: ?: y, f' O
1 |0 C: v4 o' o5 Q2 a
推荐阅读:一些常用的算法技巧总结( X/ w5 t# l" m$ g2 `/ Y1 L R9 p
* g+ Y8 J: Z, \2 e# b+ D' y% f$ W
例如在刷题的时候,我们要学会巧用双指针、数组下标法、位运算等等技巧来解决问题,可能会有意想不到的效果。我给你再找点我之前写文章的一些例子吧:* H8 i5 P; _! c
8 T/ S# b# r& b, }% a5 Y( H: \分享一道解法巧妙的算法题 b" v9 U+ o2 T3 u1 R/ w; n
& s# b; Y) z* G1 \& |
【算法技巧】位运算装逼指南 + W5 e) I y( U* A( L ) x5 ]5 a2 q. u- I" U+ g3 j5 ]; U这是个长期累积的过程,我自己也精彩在我的公众号里分享一些解题的文章,感兴趣的可以关注我的公众号:帅地玩编程。 ' y3 V/ m8 x5 p! j7 q0 q / h2 c) u) ?8 A% z. Y" o' |再说数据结构发重要性 * \0 g4 F& u4 @9 ~' k7 X8 o6 e9 ^3 v
前面我主要是说了我平时都是怎么学习算法的。在数据结构方法,我只是列举了你们一定要学习链表和树(二叉堆),但这是最基本的,刷题之前要掌握的,对于数据结构,我列举下一些比较重要的:. h. H$ v+ y. H1 H
7 q8 O! R6 m7 Q& T. o: \! ^; ~8 ?1、链表(如单向链表、双向链表)。 5 d0 O1 B% Y/ U- p, n6 n3 i$ k* V7 ~/ m* s" d: | |! H
2、树(如二叉树、平衡树、红黑树)。 7 I, E/ ^: V8 H4 o. e7 d) d; M# O7 _ l( b8 }" a$ X
3、图(如最短路径的几种算法)。 / s. f3 B5 G( [4 C$ x1 a, g, e3 ]" J: Z S
4、队列、栈、矩阵。, c$ l6 F' @6 Z; B' b& N
' b6 M0 t" J1 K) g( m
对于这些,自己一定要动手实现一遍。你可以看书,也可以看视频,新手可以先看视频,不过前期可以看视频,之后我建议是一定要看书。7 s: Z7 W# g3 T- C! y
7 T% ]% r; t9 m y8 m, q例如对于平衡树,可能你跟着书本的代码实现之后,过阵子你就忘记,不过这不要紧,虽然你忘记了,但是如果你之前用代码实现过,理解过,那么当你再次看到的时候,会很快就记起来,很快就知道思路,而且你的抽象能力等等会在不知不觉中提升起来。之后再学习红黑树啊,什么数据结构啊,都会学的很快。" Z) Q# C8 e j$ ?$ D& V
* S! [9 W- ^2 P7 p/ k# w对于有哪些值得学习的算法,我之前也总结过,这里推荐给大家程序员必须掌握的核心算法有哪些?,这篇文章居然 40多万阅读量了,有点受宠若惊。 + v t- b' F# ^+ d" S" y( r 0 j" E9 m9 y: z最最重要 * z" v* K7 W4 d u. ~! X2 w3 t; y y6 P" V5 B! B8 ?: ^
动手去做,动手去做,动手去做。重要的话说三遍。 . V. _1 P" g4 p7 |+ j9 [& e$ C! b# I" r h2 } D
千万不要找了一堆资源,订好了学习计划,我要留到某某天就来去做… 3 P, u" Q2 u* Q) R1 U; _. j' e$ u! I! g" ] @
千万不要这样,而是当你激情来的时候,就马上去干,千万不要留到某个放假日啊什么鬼了,很多这种想法的人,最后会啥也没做的。% t* _' L. A8 @8 _2 e; p
3 p2 S3 O8 z. h! I6 u; o6 f! U也不要觉得要学习的有好多啊,不知道从哪学习起。我上面说了,可以先学习最基本的,然后刷题,刷题是一个需要长期坚持的事情,一年,两年。在刷题的过程中,可以穿插和学习其他数据结构。+ x) y s) M: _
3 ~ [8 a% _( ]% I; d/ D
总结一下吧' @9 ~* [0 q, T. Q
$ O% `0 n" L* Z) p0 }
所以我给大家的建议就是,先学习基本的数据结构以及算法思想,不要盲目刷题,接着刷题的过程中,不能得过且过,尽量追求最优解,还有就是要跳出舒适区,逼自己成长,刷题的过程中,要学会分类总结。 3 Q# B' |9 O1 f/ D% ^0 p' g1 U D 4 M! l6 o4 I- ]1 K当然,最重要的,就是你去动手了,不然,一切免谈! ! h3 C( k" F/ P/ b$ D, k% y% v- w2 W1 c, C9 p4 W' @
看在熬夜写过的份上,送我个赞呗,嘻嘻。0 q4 C' s. G: k' K4 {
————————————————0 P/ O9 _' z6 w
版权声明:本文为CSDN博主「帅地」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。5 f' \5 S- n4 O" Q3 y
原文链接:https://blog.csdn.net/m0_37907797/article/details/1047651164 J% P5 r9 j z. K