最小跳数

Description:

描述:

This problem is a standard interview problem which has been featured in interview rounds of Adobe, Amazon, Oyo rooms etc.

此问题是标准的采访问题,已在Adobe,Amazon,Oyo房间等的采访回合中出现。

Problem statement:

问题陈述:

Given an array of integers where each element represents the max number of steps that can be made forward from that element. The task is to find the minimum number of jumps to reach the end of the array (starting from the first element). If an element is 0, then there is no way to move from there.

给定一个整数数组,其中每个元素代表可以从该元素进行的最大步数。 任务是找到到达数组末尾(从第一个元素开始)的最小跳转数。 如果元素为0,则无法从那里移动。

    Input:
    The first line is T, total number of test cases.  
    In the following 2*T lines,
    Each test case has two lines.
    First line is a number n denoting the size of the array.
    Next line contains the sequence of integers a1, a2, ..., an
    
    Output:
    For each test case, in a new line, 
    print the minimum number of jumps. 
    If it's not possible to reach the end the print -1

Example:

例:

    Input:
    1
    11
    1 3 5 3 1 2 6 0 6 2 4

    Output:
    4

Explanation:

说明:

    Let's first use greedy method.
    According to greedy,
    
    At first jump, 
    it will move from index 0 to 1 
    (arr[0]=1, so only 1 step jump is allowed)
    
    At second jump,
    It will move from index 1 to 4 
    (arr[1]=3, so only 3 step jump is allowed)

    At third jump,
    it will move from index 4 to 6 
    (arr[4]=2, so only 2 step jump is allowed)
    
    Now arr[6]=0, so no more jump possible. It would result -1.
    
    But, it's not the result. Thus, greedy fails. 

Since, the array value is maximum jump possible we have to check for all options up to maximum jumps. Obviously, a recursive function which would generate many overlapping sub problems. Let's check how we can solve the above example using recursion.

由于数组值是可能的最大跳转,因此我们必须检查所有选项,直到最大跳转为止。 显然,递归函数会产生许多重叠的子问题。 让我们检查一下如何使用递归解决上面的示例。

Minimum number of jumps (1)

After first jump (in this case only one move possible)

第一次跳动后(在这种情况下,只能移动一次)

Minimum number of jumps (2)

After second jump (I only took the best child (on solution path) of the recursion tree, you can try all)

第二次跳转后(我只带了递归树上最好的孩子(在解决方案路径上),可以尝试全部)

Minimum number of jumps (3)

After third jump (I only took the best child (on solution path) of the recursion tree, you can try all)

第三次跳转后(我只带了递归树上最好的孩子(在解决方案路径上),可以尝试全部)

Minimum number of jumps (4)

After fourth jump (That's end)

第四跳之后(结束)

Minimum number of jumps (5)

So, answer is 4.

答案是4。

Let's check the DP approach to solve the above problem.

让我们检查一下DP方法来解决上述问题。

Solution approach:

解决方法:

    1)  If the starting index has value 0 then we can't reach the end 
        if the array size is more than 1, so return -1.
    2)  If array size is 1, we are at the end already, so return 1 
        which is minimum jump.
    3)  Initialize DP[n]  with all elements having value INT_MAX
    4)  for i=0 to n-1
            for j=i+1 to maximum of(n-1,j+arr[i])
                //i.e,last index or upto theindex maximum jump can reach
                dp[j]=minimum(dp[j],dp[i]+1)
                where dp[i]+1=one jump added with jumps required to reach index i 
            end for
        end for
        
        // not updated in the loop refers that reach end is not possible
    5)  if dp[n-1]==INT_MAX 
            return -1
        else
            return dp[n-1]

C++ Implementation:

C ++实现:

#include <bits/stdc++.h>
using namespace std;

int min(int x,int y){
	return (x<y)?x:y;
}

int minimumjumps(vector<int> arr,int n){
	if(n==1)
		return 1;
	if(arr[0]==0)
		return -1;

	int dp[n];
	
	for(int i=0;i<n;i++)
		dp[i]=INT_MAX;
	dp[0]=0;
	for(int i=0;i<n;i++){
		for(int j=i+1;j<=((i+arr[i])>(n-1)?(n-1):(i+arr[i]));j++){
			dp[j]=min(dp[j],dp[i]+1);
		}
	}
	return dp[n-1];
}

int main()
{
	int t,n,item;
	
	cout<<"output -1 if reaching end not possible\n";
	cout<<"Enter number of testcases\n";
	scanf("%d",&t);
	
	for(int i=0;i<t;i++){
		cout<<"Enter array size\n";
		scanf("%d",&n);
		
		vector<int> a;
		
		cout<<"Enter elements:\n";
		for(int j=0;j<n;j++){
			scanf("%d",&item);
			a.push_back(item);
		}
		
		int result=minimumjumps(a,n);
		
		cout<<"Result is: ";
		if(result==INT_MAX)
			cout<<-1<<endl;
		else
			cout<<result<<endl;
	}

	return 0;
}

Output

输出量

output -1 if reaching end not possible
Enter number of testcases
1
Enter array size
11
Enter elements:
1 3 5 3 1 2 6 0 6 2 4
Result is: 4


翻译自: https://www.includehelp.com/icp/minimum-number-of-jumps.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值