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