首页 > 试题广场 >

有一排台阶,每个台阶上有一个非负整数,代表在该台阶上时能最多

[问答题]
有一排台阶,每个台阶上有一个非负整数,代表在该台阶上时能最多向前跳几个台阶。从第0个台阶开始跳,实现一个函数,判断是否能到达最后一个台阶。
例如: 4 2 2 1 0 2 返回 false
            2 1 3 1 1 0 返回 true
bool jump(int array[], int size)
{                 
}

public class Item05 {

	public static boolean flag = false;	//标志位

	/**
	 * 递归实现
	 * @param array	台阶数组
	 * @param position	当前台阶位置
	 */
	public static void jump(int[] array, int position) {
		int steps = array[position];		//可以到达的台阶数
		
		//从1到step循环,i为跳的阶数
		for (int i = 1; i <= steps; i++) {
			if (position + i == array.length - 1){
				flag = true;
				return ;
			}else
				jump(array, position + i);
		}
	}

	public static void main(String[] args) {
		int[] arrays = { 2, 1, 3, 1, 1, 0 };
		jump(arrays, 0);
		System.out.println(flag);
	}
}


发表于 2017-03-15 15:50:09 回复(1)
bool jump(vector<int> &array, int size)
{
 if (size == 1)return true;
 for (int i = 1;i<size;i++)
 {
  if (array[size - 1 - i] == i && jump(array, size - i))return true;
 }
 return false;
}
测试:
int main() {
 vector<int> in({ 4 ,2 ,2 ,1 ,0 ,2 });
 cout << jump(in, 6) << endl;
 vector<int> in2({ 2 ,1 ,3 ,1 ,1 ,0 });
 cout << jump(in2, 6) << endl;
 return 0;
}
会重复计算,为了使复杂度转变为O(n),使用辅助数组。

bool jump(vector<int> &array, int size,vector<bool>& considered)
{
 if (size == 1)return true;
 if (considered[size - 1])return false;
 considered[size - 1] = true;
 for (int i = 1;i<size;i++)
 {
  if (!considered[size - 1 - i] && array[size - 1 - i] == i && jump(array, size - i,considered))return true;
 }
 return false;
}
int main() {
 vector<int> in({ 4 ,2 ,2 ,1 ,0 ,2 });
 vector<bool> consin(in.size(), false);
 cout << jump(in, 6,consin) << endl;
 vector<int> in2({ 2 ,1 ,3 ,1 ,1 ,0 });
 vector<bool> consin2(in2.size(), false);
 cout << jump(in2, 6,consin2) << endl;
 return 0;
}

 
编辑于 2015-09-23 14:52:23 回复(0)
题目不难,注意是每个台阶最多能跳阶,也可以少于,用贪心算法,维护一个变量max用于存储还能跳多少台阶,然后遍历一遍数组,也就是依次模拟跳一个台阶,跳一次max-1,如果当前台阶所允许的最大步数大于max,就让max等于该数。如果max等于0返回false

def canJump(self, nums):
        maxStep=nums[0]
        for i in range(1,len(nums)):
            if maxStep==0:
                return False
            maxStep-=1
            if maxStep<nums[i]:
                maxStep=nums[i]
        return True

编辑于 2015-08-21 19:41:46 回复(2)
public static boolean jump(int array[],int size)
 {
  int sum = 0;
  int temp = array[0];
  boolean flat = true;
  while(sum < size)
  {
   sum +=temp;
   if(temp == 0 && sum < size)
   {
    flat = false;
    break;
   }
   temp = array[temp];
  
    }
  return flat;
}
发表于 2017-07-31 21:57:48 回复(0)
// 从后向前   逐个判断     用到标志位   【比较好理解】
#include <iostream>
using namespace std;
#include <vector>


bool jump(int array[], int size)
{       bool can = false;           
    vector<bool> is(size, false);
    is[size - 1] = true;
    for (int i = size - 2; i >= 0; i--)
    {
        for (int j =1; j <= array[i]; j++)
        {
            if (i + j <= size - 1)
            {
                if (is[i + j] == true)
                {
                    is[i] = true;
                    break;
                }
            }

        }

        if (i == 0 && is[i] == true)
        {
            can = true;
        }

    }

    return can;
}

void test_jump()
{
    int arr1[6] = {4 ,2, 2 ,1, 0, 2};
    int arr2[6] = {2 ,1 ,3 ,1 ,1 ,0};
    cout<<jump(arr1,6)<<endl;
    cout<<jump(arr2,6)<<endl;
}



int main()
{
    test_jump();
    return 0;
}

发表于 2016-09-19 10:59:26 回复(0)
//时间复杂度: o(n)~o(n^2)
//空间复杂度:o(n);
#include<stdio.h>
#include<malloc.h>
int jump(int arr[], int size)
{
	int *p_flag = NULL;
	int i, j;
	if (NULL == arr || 0 >= size)
		return 0;
	else if (1 == size)
		return 1;
	p_flag = (int*)malloc(sizeof(int)*size);	//对应第i个台阶的flag,若为1则表示可以到达,0则不可以
	memset(p_flag, 0, sizeof(int)*size);
	if (arr[0] <= 0)
		return 0;
	for (i = 1; i <= arr[0]; i++)
		p_flag[i] = 1;
	for (i = 1; i < size; i++)
	{
		//台阶从第1个开始,如果当前这个台阶i可以到达,当前台阶最大可向前走arr[i]步,
		//置标志位,使台阶第 i+1 到 i + arr[i] 台阶标志位都为1;
		if (1 == p_flag[i])
		{
			// 注意条件 i + j < size 避免溢出 
			for (j = 1; j <= arr[i] && i + j < size; j++)
			{
				p_flag[i + j] = 1;
			}
			//可能存在中间第i个台阶就可以直接跳arr[i]步,直接到最后一个台阶,此时可提前结束判断。
			if (1 == p_flag[size - 1])
				return 1;
		}
	}
	return p_flag[size - 1];//返回最后一个台阶标志
}
int main()
{
	int arr[2][20] = { { 4, 2, 2, 1, 0, 2 } ,
						{ 2, 1, 3, 1, 1, 0 } };
	printf("arr0: %d\n", jump(&arr[0][0], 6));
	printf("arr1: %d\n", jump(&arr[1][0], 6));
	return 0;
}

发表于 2016-09-03 19:47:12 回复(0)
这道题我考虑用递归的方法解题。 package zhang;

//4 2 2 1 0 2 返回 false
//2 1 3 1 1 0 返回 true
public class Step {
	private boolean flag=false;//设置标志位
	public static void main(String[] args)
	{
		int [] ladder={2,1,3,1,1,0};
		Step step=new Step();
		step.stepLadder(ladder, 0);
		if(step.flag)
			System.out.println("可以到达!");
		else
			System.out.println("无法到达!");
		
	}
	public void stepLadder(int [] ladder,int start)
	{
		int i;
		for(i=start;i<=ladder.length-1;i++)
		{
			if((ladder[start]==0)||(start+ladder[start]>ladder.length-1))
				break;
			if(start+ladder[start]==ladder.length-1)
				flag=true;
			else
				stepLadder(ladder,start+ladder[start]);
		}
	}
}从数组第一个开始跳,下次跳的位置为本次的开始位置加上跳的步数(题目只是说了最大步数,不一定非得跳最大步数)start+ladder[start],那么从ladder[start]往后的数组又是一个跳台阶问题,可以考虑用递归


发表于 2015-09-07 11:20:19 回复(0)
这题什么意思,怎么没看懂啊,总台阶数都不知道怎么判断??
发表于 2015-08-31 22:01:54 回复(0)
bool jump(int a[], int n)
{
	int j;
	vector<int>b(n,0);
	b[0] = 1;
	for (int i = 0; i < n; i++)
	{
		for (j = 0; j < i; j++)
		{
			if (a[j] >= i - j&&b[j]==1)
				b[i]=1;
		}
	}
	if (b[n - 1] == 1)
		return true;
	return false;
}

发表于 2015-08-21 20:52:31 回复(0)
大漠苍鹰 给出了一个时间复杂度和空间复杂度分别为O(n3)、O(n2)的答案。

我来给出一个时间复杂度和空间复杂度分别为O(n2)、O(n)的算法:

思路:
采用递归和一个辅助数值来实现。辅助数值boolArr[n]表示每一个台阶是否能够到达终点。
首先,初始化一个bool类型数组:boolean []boolArr = new boolean[size];
然后调用递归方法:boolean isJump(int[] arr, boolean[] boolArr, int i, int size) ;
通过递归调用初始化台阶数为0的boolArr 数组的值。然后从后到前一次判断每一个节点是否能够到达终点。

java源代码:
static boolean jump(int array[], int size) {
    boolean []boolArr = new boolean[size];
    return isJump(array, boolArr, 0, size);
}

private static boolean isJump(int[] arr, boolean[] boolArr, int i, int size) {
    // TODO Auto-generated method stub
    if (i == size - 1)
        return true;
    if (arr[i] == 0) {
        boolArr[i] = false;
    }
    boolean isNextStepOk = isJump(arr, boolArr, i + 1, size);
    if (isNextStepOk) {
        boolArr[i] = true;
    }
    if ((isNextStepOk && arr[i] > 0 ) || size - i - 1 <= arr[i])
        return true;
    for (int k = i + 2; k < i + arr[i]; k++) {
        if (boolArr[k] == true)return true;
    }
    return false;
}

编辑于 2015-02-03 17:16:55 回复(0)
首先,例子中的第一个答案是明显错误的。从3就可以跳到最后一个台阶2,而从4就可以跳到3(跳2个),所以第一个例子应该为true;即便是2后面还有个台阶,也能够到达,因为2是可达的。
该题使用了动态规划,分别在每一步的时候计算出后面的台阶那些不能到,哪些能到,从而递推到最后一个台阶。
我使用一个二维数组w记录这些中间过程,w[][]表示从i跳到j是否可行。当从i开始计算的时候,先判断i是否可达(即向之前到达i的记录进行查询,至少一个为true就行。)
其中,我没有用到题目中所给的size,该size我想是为了方便c或c++代码使用的。

java代码如下:
public class CanReachTop {
    private boolean canReach(int i, boolean[][] w) {
        if (i == 0)
            return true;
        boolean rst = false;
        for (int j = 0; j < i; j++) {
            rst = rst || w[j][i];
        }
        return rst;
    }

    public boolean jump(int array[], int size) {
        int n = array.length;
        boolean[][] w = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (canReach(i, w)) {
                    if (j - i <= array[i]) {
                        w[i][j] = true;
                        if (j == n - 1)
                            return true;
                    }
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        CanReachTop canReachTop = new CanReachTop();
        int[] a = {4, 2, 2, 1, 0, 2};
        System.out.println(canReachTop.jump(a, 3));
    }
}

编辑于 2015-02-03 17:06:39 回复(2)
bool jump(int array[], int size)
{
    if(array == NULL || size <= 0)
    {
        cout<<"输入有误..."<<endl;
        return false;
    }
    bool isLastOne = false;
    int i=0;
    while(i < size-1)
    {
        if(array[i] == 0)
        {
            isLastOne = false;
            break;
        }
        i += array[i];
    }
    if( i == size-1)
        isLastOne=true;
    return isLastOne;
}

发表于 2014-11-30 08:39:39 回复(2)
bool jump(int array[], int size)
{
    for(int i=0; i<size-1; i++)
    {
        if(array[i]==0) return false;
        i += array[i];
    }
    return true;
}

发表于 2014-11-26 20:33:23 回复(4)