zoukankan      html  css  js  c++  java
  • 55 Jump Game i && 45 Jump Game ii

    Jump Game

    Problem statement:

    Given an array of non-negative integers, you are initially positioned at the first index of the array.

    Each element in the array represents your maximum jump length at that position.

    Determine if you are able to reach the last index.

    For example:
    A = [2,3,1,1,4], return true.

    A = [3,2,1,0,4], return false.

    Analysis:

    There are two solutions for this problem, one is greedy, another is dynamic programming. The main difference is the direction.

    Solution one: 

    Greedy is the best solution for this problem, it is always forwarding(AC) O(n).

    • Loop the whole array
    • Keep a right most position where I can get, update it at each index. 
    • if right most position is always greater than current index or it is already exceed the last position of array, return true since we can get the last position
    • Once current index is greater than right most position, return false, since there is already no way to get there.

    The code is as following:

     1 class Solution {
     2 public:
     3     bool canJump(vector<int>& nums) {
     4         if(nums.empty()){
     5             return false;
     6         }
     7         
     8         // keep a indicator for current right most position we can reach
     9         int right_most = 0;
    10         
    11         // loop to enumrate all elements
    12         for(int ix = 0; ix < nums.size(); ix++){ 
    13             // if current element already exceed the right most position
    14             // return false
    15             if(right_most < ix){
    16                 return false;
    17             } else {
    18                 // we already could reache the last element
    19                 if(ix + nums[ix] >= nums.size() - 1){
    20                     return true;
    21                 } else {
    22                     // otherwise, update the right most position
    23                     right_most = max(ix + nums[ix], right_most);
    24                 }
    25             }
    26         }
    27         return false;
    28     }
    29 };

    Solution two(NOT AC):

    Dynamic programming O(n*n)

    For dynamic programming, we looks back, for each element, we enumerate all the element whose index is lower than it, and check if it is reachable.

     1 class Solution {
     2 public:
     3     // dynamic programming solution
     4     bool canJump(vector<int>& nums) {
     5         if (nums.empty()) {
     6             return false;
     7         }
     8         int size = nums.size();
     9         vector<bool> true_table(size, false);
    10         true_table[0] = true;
    11         for(int i = 1; i < nums.size(); i++){
    12             for(int j = 0; j < i; j++){
    13                 if(true_table[j] && nums[j] + j >= i){
    14                     true_table[i] = true;
    15                     break;
    16                 }
    17             }
    18         }
    19         return true_table[size - 1];
    20     }
    21 };

    --------------------------------- divide line --------------------------------------------

    Jump Game ii

    Problem Statement:

    Given an array of non-negative integers, you are initially positioned at the first index of the array.

    Each element in the array represents your maximum jump length at that position.

    Your goal is to reach the last index in the minimum number of jumps.

    For example:
    Given array A = [2,3,1,1,4]

    The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

    Note: You can assume that you can always reach the last index.

    Analysis:

    The main difference between jump game i && ii is that we should keep a minimum jump array for each element and update it for each element.

    Solution one: Greedy

    This is the accepted solution.

    Solution two: Dynamic programming(NOT AC)

     1 class Solution {
     2 public:
     3     int jump(vector<int>& nums) {
     4         if(nums.empty()){
     5             return 0;
     6         }
     7         int size = nums.size();
     8         vector<bool> can_jump(size, false);
     9         vector<int> min_jump(size, INT_MAX);
    10         // initialize start status
    11         can_jump[0] = true;
    12         min_jump[0] = 0;
    13         // dynamic programming
    14         for(int i = 1; i < nums.size(); i++){
    15             for(int j = 0; j < i; j++){
    16                 if(can_jump[j] && nums[j] + j >= i){
    17                     can_jump[i] = true;
    18                     min_jump[i] = min(min_jump[i], min_jump[j] + 1);
    19                 }
    20             }
    21         }
    22         // return end status
    23         return min_jump[size - 1];
    24     }
    25 };

    Solution two: Greedy(AC)

    we keep two variables, the first one is the most right position in current jump, the second one is the right most position in next jump.

    Just one loop to get the final solution:

     1 class Solution {
     2 public:
     3     int jump(vector<int>& nums) {
     4         // initialize 
     5         if(nums.size() < 2){
     6             return 0;
     7         }
     8         // variables
     9         int cur_jump_right_most = nums[0];
    10         int next_jump_right_most = 0;
    11         int min_jump = 1;
    12         if(cur_jump_right_most >= nums.size() - 1){
    13             return min_jump;
    14         }
    15         // O(n)
    16         for(int ix = 1; ix < nums.size(); ix++){
    17             if(ix > cur_jump_right_most){
    18                 // at boundary 
    19                 // update the cur_jump_right_most position before next_jump_right_most
    20                 cur_jump_right_most = next_jump_right_most;
    21                 min_jump++;
    22             }
    23             next_jump_right_most = max(next_jump_right_most, nums[ix] + ix);
    24             if(next_jump_right_most >= nums.size() - 1){
    25                 return ++min_jump;
    26             }
    27         }
    28         return min_jump;
    29     }
    30 };
  • 相关阅读:
    搭建集群时遇到各种奇葩问题的大招~~
    oracle初学心得(转)
    "小寒"饮食养生
    时刻修正自已的思想
    myeclipse使用
    从javascript语言本身谈项目实战(转)
    Java的内存泄漏(转)
    概念解释
    小穴位大健康——李智
    历史朝代表
  • 原文地址:https://www.cnblogs.com/wdw828/p/6414804.html
Copyright © 2011-2022 走看看