1定义

名称

意义

i

石块在数组stones中的下标

position[i]

第i个石块的position,即stones[i]

max_last_step[i]

到达第i个石块的最后一步所有可能的步长的最大值

 

2初始状态分析

由于position =1的下一跳position只能是2,3, 因此若可达,两者必有一个有石块,因此初始状态为以下三个状态之一:

(1) 若position = 2, position = 3都有石块,则状态为:

i 1 2 3
position[i] 1 2 3
max_last_step[i] 1 1 2

(2) 若position = 2有石块,position =3没有石块,则状态为:

i 1 2
position[i] 1 2
max_last_step[i] 1 1

(3) 若position = 2没有石块,position =3有石块,则状态为:

i 1 2
position[i] 1 3
max_last_step[i] 1 2

3三个推论

4算法描述

广度优先遍历每个石块。

使用一个二维数组visited记录遍历到的每个石块在数组stones中的下标和上一跳的步长。由推论一,这个二维数组的每个维度的长度都不超过stones数组的长度。

5优化

由推论三,若最后一个石块可达,则stones数组必须满足:

因此,可以先对stones数组遍历一遍,判断该必要条件是否满足。

6算法实现

具体实现中,为了减少减法运算,把二维数组visited中的上一跳步长改为了下一跳最小步长,即上一跳步长-1

#include <stdbool.h>
#include <stdlib.h>struct record {int stone_index;int min_step;
};bool binary_search(int *arr, int size, int elem, int *index)
{int start = 2;int end = size - 1;int mid;while (start <= end){mid = (start + end) >> 1;if (elem == arr[mid]){*index = mid;return true;}if (elem < arr[mid]) end = mid - 1;else start = mid + 1;}*index = start;return false;
}bool can_cross(int* stones, int stonesSize, int **visited, struct record *queue)
{int last_stone = stones[stonesSize - 1];struct record *curr;int front = 0;int tail = 0;int stone_position;int stone_index;bool is_stone;int curr_min_step;curr = &queue[tail++];curr->stone_index = 1;curr->min_step = 0;visited[1][0] = 1;while (front != tail){curr = &queue[front++];curr_min_step = curr->min_step;stone_position = stones[curr->stone_index] + curr_min_step;curr_min_step--;if (stone_position == last_stone || stone_position + 1 == last_stone ||stone_position + 2 == last_stone) return true;is_stone = binary_search(stones, stonesSize, stone_position, &stone_index);if(is_stone && curr_min_step >= 0 && !visited[stone_index][curr_min_step]){curr = &queue[tail++];curr->stone_index = stone_index;curr->min_step = curr_min_step;visited[stone_index][curr_min_step] = 1;}stone_position++;curr_min_step++;if (stone_index < stonesSize && stones[stone_index] < stone_position){stone_index++;}if (stone_index < stonesSize && stones[stone_index] == stone_position && !visited[stone_index][curr_min_step]){curr = &queue[tail++];curr->stone_index = stone_index;curr->min_step = curr_min_step;visited[stone_index][curr_min_step] = 1;}stone_position++;curr_min_step++;if (stone_index < stonesSize && stones[stone_index] < stone_position){stone_index++;}if (stone_index < stonesSize && stones[stone_index] == stone_position && !visited[stone_index][curr_min_step]){curr = &queue[tail++];curr->stone_index = stone_index;curr->min_step = curr_min_step;visited[stone_index][curr_min_step] = 1;}}return false;
}bool canCross(int* stones, int stonesSize) {int **visited;struct record *queue;bool res;int i;if (stones[1] != 1) return false;if (stonesSize == 2) return true;visited = (int **)malloc(sizeof(*visited) * stonesSize);for (i = 0; i < stonesSize; i++){visited[i] = (int *)malloc(sizeof(*visited[0]) * stonesSize);memset(visited[i], 0, sizeof(*visited[0]) * stonesSize);}queue = (struct record *)malloc(sizeof(*queue) * stonesSize * stonesSize);res = can_cross(stones, stonesSize, visited, queue);for (i = 0; i < stonesSize; i++){free(visited[i]);}free(visited);free(queue);return res;
}

403. Frog Jump相关推荐

  1. LeetCode 403 Frog Jump 青蛙过河 Javascirpt 解决方案

    代码 /*** @param {number[]} stones* @return {boolean}*/ var canCross = function(stones) {let len = sto ...

  2. Leetcode-403.Frog Jump(青蛙跳石头)

    今天的题目是:Leetcode 403-青蛙跳 A frog is crossing a river. The river is divided into x units and at each un ...

  3. 算法练习(21):Frog Jump

    题意:给出石头的位置,然后青蛙每一跳的距离a和上一跳距离k满足(k==a||k==a-1||k==a+1),第一个石头是位置0,第一跳只能距离为1. 分析与思路:这个题目用遍历搜索所有的路线是肯定可以 ...

  4. html5 frog jump,frog-jump

    https://leetcode.com/problems/frog-jump///受以下网页启发,用递归可行// https://discuss.leetcode.com/topic/59337/e ...

  5. LeetCode All in One 题目讲解汇总(持续更新中...)

    原文地址:https://www.cnblogs.com/grandyang/p/4606334.html 终于将LeetCode的大部分题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开 ...

  6. taoqick 搜索自己CSDN博客

    L1 L2正则化和优化器的weight_decay参数 kaiming初始化的推导 Pytorch动态计算图 Pytorch自动微分机制 PyTorch中在反向传播前为什么要手动将梯度清零? 通俗讲解 ...

  7. 考研词汇 用语言记忆

    根据目前的时间安排及复习进度,相信大家都泡在英语堆里狂记单词,我也一样   不过在偶尔看了下面的单词复习方法后,我试着并为之坚持下来,感觉收获真的不一样    因此奉献给大家,希望对大家有所帮助! 告 ...

  8. 7000词汇这么背我比较可以接受,连续看20天足以

    16天记住7000考研词汇(第一天) 1.With my own ears I clearly heard the heart beat of the nuclear bomb. 我亲耳清楚地听到原子 ...

  9. 800个有趣句子帮你记忆7000个单词

    800个有趣句子帮你记忆7000个单词 1. With my ownears I clearly heard the heart beat of the nuclear bomb. 我亲耳清楚地听到原 ...

  10. [转]800个有趣句子帮你记忆7000个单词

    1. With my own ears I clearly heard the heart beat of the nuclear bomb. 我亲耳清楚地听到原子弹的心脏的跳动. 2. Next y ...

最新文章

  1. Task三个列子的分享
  2. 计算机视觉 | 计算机界国际学术会议和期刊目录
  3. 关于codeblocks插件(持续更新)
  4. 启动mq 在虚拟机中_记在使用rocketmq client客户端过程中踩到的坑
  5. MySQL5.7.9安装与配置优化
  6. 怪兽充电宝 共享充电宝源码
  7. IntelliJ IDEA中Maven项目的默认JDK版本
  8. testng_TestNG注释
  9. 微软知识库kb是什么?如何搜索Microsoftwindowsknowledgebase
  10. CSS实现选中图片效果
  11. java毕业设计校园闲置物品租售系统mybatis+源码+调试部署+系统+数据库+lw
  12. 【推荐】程序员必读的三十本经典巨作
  13. hdu——4379 ——The More The Better
  14. QQ自定义登录模拟器
  15. 更改zabbix数据库mandatory
  16. 如何修改树莓派系统时间
  17. 三层交换机配置多网段互访并上网:型号:交换机TPLINK(TL-SG5428) 路由器TPLINK(TL-WVR600G)
  18. java 生成dump_Java生成堆内存dump
  19. C/C++ 排序专题
  20. 数据库系列之TiDB备份恢复

热门文章

  1. C++对象数组的实例学习
  2. DM642图像处理程序的主要结构
  3. linux 如何查看 块设备_理解Linux操作系统中的块设备
  4. c++ hashset的用法_C++ set crbegin() 使用方法及示例
  5. xml property标签注入一个类变量_依赖注入的学习
  6. centos eclipse php,centos打不开eclipse怎么办?
  7. python支持按指定字符串分割成数组_按固定元素数目分割数组- perl,python
  8. python程序运行后没有反应_为什么我的电脑在运行这个python程序时速度变慢,没有反应?...
  9. 布线问题 nyoj38
  10. 栈解决中缀表达式转后缀表达式_第3章栈和队列,中缀表达式转换成后缀表达式...