Frog Jump

来源:互联网 发布:pnp网络摄像机手机端 编辑:程序博客网 时间:2024/05/21 22:44

Frog Jump - LeetCode

题目:
A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.
Given a list of stones’ positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit.
If the frog’s last jump was k units, then its next jump must be either k - 1, k, or k + 1 units. Note that the frog can only jump in the forward direction.
Note:
1.The number of stones is ≥ 2 and is < 1,100.
2.Each stone’s position will be a non-negative integer < 231.
3.The first stone’s position is always 0.


这道题问我们青蛙是否能跳到最后一块石头,下面是题目给出的例子:

[0,1,3,5,6,8,12,17],这个数组记录了石头所在位置,第一块石头在位置0,第二块在位置1,第三块在位置3,以此类推。
青蛙从第一快石头开始跳,第一次只能跳一步,接下来如果上一次跳了k步,那么这次只能跳k-1,k或k+1步。

位置 步数 到达 0 1 1 1 2 3 3 2 5 5 3 8 8 4 12 12 5 17

所以这个例子中,青蛙可以到达最后一块石头的。

这道题目可以用bfs或者dfs来解决,但bfs不是很适合,因为bfs是一层一层往外扩展的,这样就会在求出从起点能到达的所有点后(也不一定是所有点,总之就是前面的绝大部分点),在判断是否能到达终点,但是对于这个问题我们并不需要知道从起点开始可以到达哪些点,我们好奇的只是能不能到达终点,所以bfs会求出很多我们不需要的东西。而dfs每次会先搜到低,会先求从起点开始能够到达的最深的点,这样如果问题有解的话能够以较快的速度找到解。

其实我一开始用了bfs,交了几次都超时,然后才改成了dfs。

#include <iostream>#include <cstdlib>#include <vector>#include <queue>#include <map>using namespace std;class Node{public:    int currentPosition;    int currentJump;    Node(int p, int j) {        currentPosition = p;        currentJump = j;    }    ~Node() {}};class Solution {public:    map<int,int> Stones;    int lastpos;    bool canCross(vector<int>& stones) {        int s = stones.size();        if (stones[s-1] == s-1) return true;        if (stones[s-1] > (s-1)*s/2) return false;        for (int i = 0; i < stones.size(); i++) {            this->Stones[stones[i]] = 1;        }        this->lastpos = stones[stones.size()-1];        Node start = Node(0, 0);        return solve(start);    }    bool solve(Node n) {        if (n.currentPosition == this->lastpos) return true;        for (int i = 1; i > -2; i--) {            int jump = n.currentJump+i;            if (jump <= 0) continue;            int newpos = n.currentPosition+jump;            if (this->Stones.find(newpos) != Stones.end()) {                Node newNode = Node(newpos, jump);                if (solve(newNode)) return true;            }        }        return false;    }};

别人的代码,,和我的解法基本一样,就不多解释了

class Solution {public:        /*        DFS - from each location jump to legal / reachable location              Jump as far as you can i.e. prioritize long jump paths first    */    bool canCross(vector<int>& stones) {        if (stones.size() == 0) {            return true;        }        unordered_map<int, int> lookup;        for (int i = 0; i < stones.size(); ++i) {            // The two stones are too far away as max value of            // jump at index i is stones[i]            if (i > 3 && (stones[i] - stones[i - 1]) > i) {                return false;            }             lookup[stones[i]] = i;        }        return canCross(stones, lookup, 0, 1);    }private:    struct hashVal {        size_t operator()(pair<int, int> val) const {            return size_t((hash<int>()(val.first) ^ hash<int>()(val.second)));        }    };    unordered_map<pair<int, int>, int, hashVal> memo;    bool canCross(vector<int>& stones, unordered_map<int, int>& lookup, int start, int jump) {        // Out of bound or non positive jump value        if (jump <= 0 || start >= stones.size()) {            return false;        }        auto sol = memo.find(make_pair(start, jump));        if (sol != memo.end()) {            return (*sol).second;        }        // Target stone distance        auto it = lookup.find(stones[start] + jump);        // Return if jump in water        if (it == lookup.end()) {            return false;        }         int end = (*it).second;        // Done if last stone        if (end == stones.size() - 1) {            return true;        }        // Jump to a location as far as possible i.e jum to j + 1 first then j and j - 1        if (canCross(stones, lookup, end, jump + 1) ||            canCross(stones, lookup, end, jump) ||            canCross(stones, lookup, end, jump - 1)) {            return true;        }        return false;    }};
原创粉丝点击