1+ H
2+ 1533535937
3+ tags : DP , Hash Table
4+
5+ Frog jump 的题目稍微需要理解 : 每个格子可以 jump k -1 , k , k +1 steps , 而k取决于上一步所跳的步数 . 默认 0 ->1 一定是跳了1步 .
6+
7+ 注意 : int [] stones 里面是stone所在的unit (不是可以跳的步数 , 不要理解错 ).
8+
9+ #### DP
10+ - 原本想按照corrdiante dp 来做 , 但是发现很多问题 , 需要track 不同的 possible previous starting spot .
11+ - 根据jiuzhang答案 : 按照定义 , 用一个 map of <stone , Set <possible # steps to reach stone >>
12+ - 每次在处理一个stone的时候 , 都根据他自己的 set of <previous steps >, 来走下三步 : k -1 , k , or k +1 steps .
13+ - 每次走一步 , 查看 stone + step 是否存在 ; 如果存在 , 就加进 next position : `stone +step `的 hash set 里面
14+
15+ ##### 注意init
16+ - `dp .put (stone , new HashSet <>())` mark 每个stone的存在
17+ - `dp .get (0 ).add (0 )` init condition , 用来做 dp .put (1 , 1 )
18+
19+ ##### 思想
20+ - 最终做下来思考模式 , 更像是BFS的模式 : starting from (0 ,0 ), add all possible ways
21+ - 然后again , try next stone with all possible future ways ... etc
22+
23+ ```
24+
25+ /*
26+ A frog is crossing a river. The river is divided into x units and at each unit
27+ there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.
28+
29+ Given a list of stones' positions (in units) in sorted ascending order,
30+ determine if the frog is able to cross the river by landing on the last stone.
31+ Initially, the frog is on the first stone and assume the first jump must be 1 unit.
32+
33+ If the frog's last jump was k units, then its next jump must be either k - 1, k, or k + 1 units.
34+ Note that the frog can only jump in the forward direction.
35+
36+ Note:
37+
38+ The number of stones is ≥ 2 and is < 1,100.
39+ Each stone's position will be a non-negative integer < 231.
40+ The first stone's position is always 0.
41+ Example 1:
42+
43+ [0,1,3,5,6,8,12,17]
44+
45+ There are a total of 8 stones.
46+ The first stone at the 0th unit, second stone at the 1st unit,
47+ third stone at the 3rd unit, and so on...
48+ The last stone at the 17th unit.
49+
50+ Return true. The frog can jump to the last stone by jumping
51+ 1 unit to the 2nd stone, then 2 units to the 3rd stone, then
52+ 2 units to the 4th stone, then 3 units to the 6th stone,
53+ 4 units to the 7th stone, and 5 units to the 8th stone.
54+ Example 2:
55+
56+ [0,1,2,3,4,8,9,11]
57+
58+ Return false. There is no way to jump to the last stone as
59+ the gap between the 5th and 6th stone is too large.
60+ */
61+
62+ // simplified with helper function
63+ class Solution {
64+ public boolean canCross (int [] stones ) {
65+ if (stones == null || stones .length == 0 ) return false ;
66+ Map <Integer , Set <Integer >> dp = new HashMap <>();
67+ // Init: all stone slots has nothing on them
68+ for (int stone : stones ) {
69+ dp .put (stone , new HashSet <>());
70+ }
71+ dp .get (0 ).add (0 ); // such that dp.get(0) will move (dp, 0-stone, 1-step) on index 0
72+ for (int stone : stones ) {
73+ for (int k : dp .get (stone )) {
74+ move (dp , stone , k );
75+ move (dp , stone , k + 1 );
76+ move (dp , stone , k - 1 );
77+ }
78+ }
79+ int lastStone = stones [stones .length - 1 ];
80+ return !dp .get (lastStone ).isEmpty (); // able to reach
81+ }
82+
83+ private void move (Map <Integer , Set <Integer >> dp , int stone , int step ) {
84+ if (step > 0 && dp .containsKey (stone + step )) {
85+ dp .get (stone + step ).add (step );
86+ }
87+ }
88+ }
89+
90+ // original
91+ class Solution {
92+ public boolean canCross (int [] stones ) {
93+ if (stones == null || stones .length == 0 ) return false ;
94+ int n = stones .length ;
95+ Map <Integer , Set <Integer >> dp = new HashMap <>();
96+ for (int stone : stones ) {
97+ dp .put (stone , new HashSet <>());
98+ }
99+ dp .get (0 ).add (0 );
100+ for (int stone : stones ) {
101+ for (int k : dp .get (stone )) {
102+ if (k - 1 > 0 && dp .containsKey (stone + k - 1 )) { // k - 1
103+ dp .get (stone + k - 1 ).add (k - 1 );
104+ }
105+ if (k > 0 && dp .containsKey (stone + k )) {// k
106+ dp .get (stone + k ).add (k );
107+ }
108+ if (k + 1 > 0 && dp .containsKey (stone + k + 1 )) { // k + 1
109+ dp .get (stone + k + 1 ).add (k + 1 );
110+ }
111+ }
112+ }
113+ int lastStone = stones [n - 1 ];
114+ return !dp .get (lastStone ).isEmpty (); // able to reach
115+ }
116+ }
117+ ```
0 commit comments