Title Description
Given an array of non-negative integers, you is initially positioned at the first index of the array.
Each element of the array represents your maximum jump length is at that position.
Determine if you is able to reach the last index.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
For the above data, use Help to understand:
According to the topic, each element in the array represents the furthest distance that can be jumped out from that position, asking whether the last element of the array, starting with the first element (index=0), can be reached, and the last element is considered to be the end point . There are several points to note:
- All non-negative elements in the array, so there is no fallback situation;
- The topic asks to reach the end point , and does not want to stop at the end, therefore, if can skip the end point is also successful;
- The topic describes the maximum distance each element can reach from that position, but it can actually not jump that far away. For example, the first array in the first element is 2, then you can skip step second at element 3 from that position, or you can jump 2 steps to third bit element 1.
Using the solution of dynamic programming
The subject can be done with the idea of dynamic planning, to investigate the maximum distance each position can reach. The maximum distance that the K element can reach, which may be:
- a x (The farthest distance from the k-1 position may not actually jump to the K position at this time)
- k+nums[k] (Farthest distance from K position)
To traverse the farthest distance of an array element, use the farthest distance to determine if you can jump to the end , as follows:
- The farthest distance before the K element is reached is a x ;
- If max<k , you cannot jump to the K position and the program returns false;
- Otherwise, calculate the maximum distance that can be reached at K position, Max_dis_at_k = max > k + num[k]? Max:k + num[k];
- If Max_dis_at_k > array length, the program returns TRUE.
The program can get results at most as long as it is traversed, so the time complexity is O(n) 。
The code is as follows:
classSolution { Public:BOOLCanjump ( vector<int>& Nums) {if(!nums.size ())return false;intmax = nums[0]; for(inti =1; I! = Nums.size (); ++i) {if(i > Max)return false;Else if(Nums[i] + i >= nums.size ()-1)return true;Else if(Nums[i] + i > max) max = nums[i] + i; }return true; }};
Alternative solutions for not using dynamic programming
When I finished the subject, I looked up the relevant information, before there are other blog notes, this is titled a very classic dynamic Planning topic, unfortunately I have not yet learned the dynamic planning, so in the beginning to see the problem, not using dynamic programming intuition, Spare a good big bend to think of the above solution.
The initial idea is that since the elements in the array are non-negative, you can reach the end point as long as the element values are all positive. The reason for the inability to reach the end point is that the 0 elements in the array, we can assume that the array of 0 elements in some position equivalent to an absorption state , the element jumps to that position can not go forward. For example, the second example, so in the program to determine whether 0 is the absorption state can be judged to reach the end.
The absorption state is judged by: if all elements before the 0 element in the array skip the distance not exceeding 0, then 0 is the absorption state .
- For the 0 element of position I, traversing forward from the j=i-1 element, judging Nums[j] + J > i is established,
- If it is established, the program can successfully skip the I position of the 0 elements, continue to traverse the search for 0 elements
- If not, the 0 element of the I position is the absorption state , unable to reach the end point and return false.
According to this idea, we can do forward and reverse traversal to find the absorption state .
forward Traversal:
classSolution { Public:BOOLCanjump ( vector<int>& Nums) {if(!nums.size ())return false;inti =0; while(I < nums.size ()-1) {if(Nums[i] = =0) {intj = i-1; while(I < nums.size ()-1&&!nums[i]) i++; i--;BOOLFlag =false; while(J >=0) {if(Nums[j] + j >= nums.size ()-1)return true;Else if(Nums[j] + j > i) {i = nums[j] + j; Flag =true; Break; } j--; }if(!flag)return false; }Else{i = i + nums[i]; } }return true; }};
Reverse Traversal
classSolution { Public:BOOLCanjump ( vector<int>& Nums) {if(!nums.size ())return false;if(nums.size () = =1)return true;inti = nums.size ()-1; for(inti = nums.size ()-1; I >=0; -I.) {if(Nums[i] = =0) {intj = i-1;BOOLFlag =false; while(J >=0) {if((i = = Nums.size ()-1&& nums[j]+j ==i) | | NUMS[J] + J > i) {flag =true; i = j +1; Break; } j--; }if(!flag)return false; } }return true; }};
Postscript
Compared with the alternative solution and dynamic programming method, the solution of dynamic programming is elegant, the idea is clear, the process of writing code is also very enjoyable, and I have to sigh to learn the algorithm well. MIT "Introduction to Algorithms," the teacher in the Open class said in the first class, to write a good program, you can write code every day for two years, or you can choose an algorithm class, really very reasonable.
Leetcode (All) jump Game (Dynamic planning)