青蛙跳-LintCode

一只青蛙正要过河,这条河分成了 x 个单位,每个单位可能存在石头,青蛙可以跳到石头上,但它不能跳进水里。
按照顺序给出石头所在的位置,判断青蛙能否到达最后一块石头所在的位置。刚开始时青蛙在第一块石头上,假设青蛙第一次跳只能跳一个单位的长度。
如果青蛙最后一个跳 k 个单位,那么它下一次只能跳 k - 1 ,k 或者 k + 1 个单位。注意青蛙只能向前跳。

注意事:
石头的个数 >= 2并且 <= 1100。
每块石头的位置是一个非负数并且 < 2^31。
第一块石头的位置总是 0.

样例:

给出石头的位置为 [0,1,3,5,6,8,12,17]

总共8块石头。
第一块石头在 0 位置,第二块石头在 1 位置,第三块石头在 3 位置等等......
最后一块石头在 17 位置。

返回 true。青蛙可以通过跳 1 格到第二块石头,跳 2 格到第三块石头,跳 2 格到第四块石头,跳 3 格到第六块石头,跳 4 格到第七块石头,最后跳 5 格到第八块石头。

给出石头的位置为 `[0,1,2,3,4,8,9,11]`
返回 false。青蛙没有办法跳到最后一块石头因为第五块石头跟第六块石头的距离太大了。
#ifndef C622_H
#define C622_H
#include<iostream>
#include<vector>
#include<map>
#include<set>
using namespace std;
class Solution {
public:
    /*
    * @param stones: a list of stones' positions in sorted ascending order
    * @return: true if the frog is able to cross the river or false
    */
    bool canCross(vector<int> &stones) {
        // write your code here
        int len = stones.size();
        map<int, set<int>> m;//存放可以到达的位置以及由哪一位置到达现在的位置
        m[1].insert(0);
        for (int i = 1; i < len; ++i)
        {
            if (i == 1)      //对于i==1,stepLength=1,则1(位置)可以到2,3位置,就在m[2],m[3]中添加1
            {
                if (stones[i] == 1)
                {
                    m[2].insert(1);
                    m[3].insert(1);
                }
                else
                    return false;
            }
            else
            {
                //m中没有stones[i],说明没有位置可以到达stones[i]位置
                if (m.find(stones[i]) == m.end())
                {
                    return false;
                }
                else
                {
                    //num表示上一步跳num个单位,遍历set,得到目前位置可以跳的所有单位
                    //长度(num-1,num,num+1),计算可以跳到的位置pos,并在其set中添加现在的位置
                    for (auto c : m[stones[i]])
                    {
                        for (int j = -1; j <= 1; ++j)
                        {
                            int num = stones[i] - c + j;
                            if (num > 0)
                            {
                                m[stones[i] + num].insert(stones[i]);
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
};
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值