- 青蛙过河
一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。
给你石子的位置列表 stones(用单元格序号 升序 表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一块石子上)。
开始时, 青蛙默认已站在第一块石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格 1 跳至单元格 2 )。
如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1 个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。
示例 1:
输入:stones = [0,1,3,5,6,8,12,17]
输出:true
解释:青蛙可以成功过河,按照如下方案跳跃:跳 1 个单位到第 2 块石子, 然后跳 2 个单位到第 3 块石子, 接着 跳 2 个单位到第 4 块石子, 然后跳 3 个单位到第 6 块石子, 跳 4 个单位到第 7 块石子, 最后,跳 5 个单位到第 8 个石子(即最后一块石子)。
示例 2:
输入:stones = [0,1,2,3,4,8,9,11]
输出:false
解释:这是因为第 5 和第 6 个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。
提示:
2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0
题解
很有趣的题目,我们这样,按题目要求,到达某个位置pos的跳跃单位为K,于是可以从pos跳跃单位为K+1,K,K-1,于是我们判断跳跃之后的新位置new_pos是否在数组中存在,如果存在,就把new_pos这个位置储存下这个跳跃单位,比如,跳到位置5,前面的位置到达位置5跳跃单位有[1,3,4,7],那从位置5就可以:
[1+1,1,1-1]
[3+1,3,3-1]
[4+1,4,4-1]
[7+1,7,7-1]
为了快速去重,我们利用set储存,为了快速判断跳跃到的新位置new_po是否存在我们写个二分查找函数判断。
AC代码
class Solution {
public:
int search(vector<int>& stones,int pos,int num)
{
int l=pos+1,r=stones.size()-1,fin=-1;
while(l<=r)
{
int mid=(l+r)/2;
if(stones[mid]>=num)
{
r=mid-1;
fin=mid;
}
else l=mid+1;
}
return fin;
}
set<int>q[2005];
int xx[3]={-1,0,1};
bool canCross(vector<int>& stones) {
q[0].insert(0);
set<int>::iterator it;
for(int i=0;i<stones.size();i++)
{
for(it=q[i].begin();it!=q[i].end();it++)
{
for(int j=0;j<3;j++)
{
int fin=search(stones,i,stones[i]+*it+xx[j]);
if(fin==-1)continue;
if(stones[fin]!=stones[i]+*it+xx[j])continue;
q[fin].insert(*it+xx[j]);
}
}
}
return q[stones.size()-1].size()>0;
}
};
话说,,,,我要判断某个位置是否存在,干嘛不用map直接映射,还要自己手写一个二分查找函数????
人傻了,有兴趣的同学把二分查找函数换成map也可以的,差不多的。