每日力扣:403. 青蛙过河

2024-02-15 16:38
文章标签 力扣 每日 青蛙 过河 403

本文主要是介绍每日力扣:403. 青蛙过河,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

package com.sample.suncht.algo;import java.util.*;/*** 403. 青蛙过河* <p>* 一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。* <p>* 给定石子的位置列表(用单元格序号升序表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。* <p>* 如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。* <p>* 请注意:* <p>* 石子的数量 ≥ 2 且 < 1100;* 每一个石子的位置序号都是一个非负整数,且其 < 231;* 第一个石子的位置永远是0。* 示例 1:* <p>* [0,1,3,5,6,8,12,17]* <p>* 总共有8个石子。* 第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置,* 第三个石子在序号为3的单元格的位置, 以此定义整个数组...* 最后一个石子处于序号为17的单元格的位置。* <p>* 返回 true。即青蛙可以成功过河,按照如下方案跳跃:* 跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着* 跳2个单位到第4块石子, 然后跳3个单位到第6块石子,* 跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。* 示例 2:* <p>* [0,1,2,3,4,8,9,11]* <p>* 返回 false。青蛙没有办法过河。* 这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。* * * 执行用时 : 63 ms, 在Frog Jump的Java提交中击败了58.82% 的用户*/
public class CanCross403 {public boolean canCross(Integer[] stones) {if (stones == null || stones.length < 2) {return true;}if (stones.length == 2) {return stones[1] == 1;}int[] res = new int[1]; //判断是否达到了最后一个节点,如果达到了,说明青蛙可以过河Map<Integer, Boolean> map = new LinkedHashMap<Integer, Boolean>();allowJump(stones, 0, 0, map, res);return res[0] == 1;}private void allowJump(Integer[] stones, int pos, int jump, Map<Integer, Boolean> map, int[] res) {if (res[0] != 1 && pos >= stones.length - 1) {res[0] = 1;return;}//一开始使用"pos:jump:i"字符串作为缓存,但是其实只用“pos:jump”就可以了// 最后为了提高速度,改成整型位运算Integer mark = pos ^ (jump << 11);if (map.containsKey(mark)) {return;}for (int i = pos + 1; i < stones.length; i++) {int dist = stones[i] - stones[pos];//如果dist小于jump-1,需要继续执行if (dist < jump - 1) {continue;}if (dist <= jump + 1) {map.put(mark, true);if (res[0] != 1) { //如果青蛙已过河,则不需要再进行计算了allowJump(stones, i, dist, map, res);}} else {//如果dist大于jump+1,那么后面都一定是大于jump+1,则直接退出,不需要计算map.put(mark, false);return;}}}public static void main(String[] args) {List<AlgoHelper.InputParams<Integer[], Boolean>> datas = new ArrayList<>();datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 3, 5, 6, 8, 12, 17}, true));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 3, 5, 6, 8, 12}, true));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 2, 3, 4, 8, 9, 11}, false));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 4}, false));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 3, 4, 10}, false));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 2}, false));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1}, true));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 2}, true));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, true));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 2, 3, 4, 5, 6, 12}, false));datas.add(new AlgoHelper.InputParams<>(new Integer[]{0, 1, 3, 6, 10, 15, 16, 21}, true));AlgoHelper.assertResult(datas, new CanCross403()::canCross);}}

结果:

这篇关于每日力扣:403. 青蛙过河的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/711927

相关文章

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 示例 2: 输入:height

每日一题——第八十一题

打印如下图案: #include<stdio.h>int main() {int i, j;char ch = 'A';for (i = 1; i < 5; i++, ch++){for (j = 0; j < 5 - i; j++){printf(" ");//控制空格输出}for (j = 1; j < 2 * i; j++)//条件j < 2 * i{printf("%c", ch