Java每日一练(20230405)

目录

1. 地下城游戏  🌟🌟🌟

2. 汇总区间  🌟🌟

3. 寻找旋转排序数组中的最小值 II  🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


1. 地下城游戏

一些恶魔抓住了公主(P)并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。

为了尽快到达公主,骑士决定每次只向右或向下移动一步。

编写一个函数来计算确保骑士能够拯救到公主所需的最低初始健康点数。

例如,考虑到如下布局的地下城,如果骑士遵循最佳路径 右 -> 右 -> 下 -> 下,则骑士的初始健康点数至少为 7

-2 (K)-33
-5-101
1030-5 (P)

说明:

  • 骑士的健康点数没有上限。

  • 任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

出处:

https://edu.csdn.net/practice/24744062

代码:

import java.util.Scanner;
public class calculateMinimumHP {
    public static class Solution {
        public int calculateMinimumHP(int[][] dungeon) {
            int row = dungeon.length;
            int col = dungeon[0].length;
            int[][] dp = new int[row][col];
            for (int i = row - 1; i >= 0; i--) {
                for (int j = col - 1; j >= 0; j--) {
                    if (i == row - 1 && j == col - 1) {
                        dp[i][j] = Math.max(1, 1 - dungeon[i][j]);
                    } else if (i == row - 1) {
                        dp[i][j] = Math.max(1, dp[i][j + 1] - dungeon[i][j]);
                    } else if (j == col - 1) {
                        dp[i][j] = Math.max(1, dp[i + 1][j] - dungeon[i][j]);
                    } else {
                        dp[i][j] = Math.max(1, Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]);
                    }
                }
            }
            return dp[0][0];
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[][] nums = {{-2,-3,3},{-5,-10,1},{10,30,-5}};
        System.out.println(s.calculateMinimumHP(nums));
    }
}

输出:

7


2. 汇总区间

给定一个无重复元素的有序整数数组 nums 。

返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。

列表中的每个区间范围 [a,b] 应该按如下格式输出:

  • "a->b" ,如果 a != b
  • "a" ,如果 a == b

示例 1:

输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]
解释:区间范围是:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"

示例 2:

输入:nums = [0,2,3,4,6,8,9]
输出:["0","2->4","6","8->9"]
解释:区间范围是:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"

示例 3:

输入:nums = []
输出:[]

示例 4:

输入:nums = [-1]
输出:["-1"]

示例 5:

输入:nums = [0]
输出:["0"]

提示:

  • 0 <= nums.length <= 20
  • -231 <= nums[i] <= 231 - 1
  • nums 中的所有值都 互不相同
  • nums 按升序排列

出处:

https://edu.csdn.net/practice/24744063

代码1: 原题代码(双指针)

import java.util.*;
public class summaryRanges {
    public static class Solution {
        public List<String> summaryRanges(int[] nums) {
            List<String> list = new ArrayList<>();
            int pre = 0;
            int next = 0;
            for (int i = 0; i < nums.length; i++) {
                if (i + 1 < nums.length && nums[i + 1] - nums[i] == 1) {
                    next = i + 1;
                } else {
                    if (next < i)
                        next = i;
                    if (pre != next) {
                        list.add(nums[pre] + "->" + nums[next]);
                        pre = i + 1;
                    }
                    if (pre == next) {
                        list.add(nums[pre] + "");
                        pre = i + 1;
                    }
                }
            }
            return list;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] nums = {0,1,2,4,5,7};
        System.out.println(s.summaryRanges(nums));
        int[] nums2 = {0,2,3,4,6,8,9};
        System.out.println(s.summaryRanges(nums2));
    }
}

代码2: 双指针 

import java.util.*;
public class summaryRanges {
    public static class Solution {
        public List<String> summaryRanges(int[] nums) {
            List<String> res = new ArrayList<>();
            if (nums == null || nums.length == 0) {
                return res;
            }
            int start = nums[0]; // 记录区间起点
            int end = nums[0]; // 记录区间终点
            for (int i = 1; i < nums.length; i++) {
                if (nums[i] != end + 1) { // 区间中断
                    if (start == end) { // 区间只有一个数字
                        res.add(String.valueOf(start));
                    } else { // 区间有多个数字
                        res.add(start + "->" + end);
                    }
                    start = nums[i]; // 更新区间起点
                }
                end = nums[i]; // 更新区间终点
            }
            // 循环完毕,最后一个区间还没有加入
            if (start == end) {
                res.add(String.valueOf(start));
            } else {
                res.add(start + "->" + end);
            }
            return res;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] nums = {0,1,2,4,5,7};
        System.out.println(s.summaryRanges(nums));
        int[] nums2 = {0,2,3,4,6,8,9};
        System.out.println(s.summaryRanges(nums2));
    }
}

代码3: 暴力枚举

import java.util.*;
public class summaryRanges {
    public static class Solution {
        public List<String> summaryRanges(int[] nums) {
            List<String> res = new ArrayList<>();
            if (nums == null || nums.length == 0) {
                return res;
            }
            int start = nums[0]; // 记录区间起点
            for (int i = 1; i <= nums.length; i++) {
                if (i == nums.length || nums[i] != nums[i - 1] + 1) { // 区间中断
                    if (start == nums[i - 1]) { // 区间只有一个数字
                        res.add(String.valueOf(start));
                    } else { // 区间有多个数字
                        res.add(start + "->" + nums[i - 1]);
                    }
                    if (i < nums.length) { // 更新区间起点
                        start = nums[i];
                    }
                }
            }
            return res;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] nums = {0,1,2,4,5,7};
        System.out.println(s.summaryRanges(nums));
        int[] nums2 = {0,2,3,4,6,8,9};
        System.out.println(s.summaryRanges(nums2));
    }
}

输出:

[0->2, 4->5, 7]
[0, 2->4, 6, 8->9]


3. 寻找旋转排序数组中的最小值 II

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
  • 若旋转 7 次,则可以得到 [0,1,4,4,5,6,7]

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个可能存在 重复 元素值的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

示例 1:

输入:nums = [1,3,5]
输出:1

示例 2:

输入:nums = [2,2,2,0,1]
输出:0

提示:

  • n == nums.length
  • 1 <= n <= 5000
  • -5000 <= nums[i] <= 5000
  • nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转

进阶:

  • 这道题是 寻找旋转排序数组中的最小值的延伸题目。
  • 允许重复会影响算法的时间复杂度吗?会如何影响,为什么?

出处:

https://edu.csdn.net/practice/24744064

代码:

import java.util.*;
public class findMin {
    public static class Solution {
        public int findMin(int[] nums) {
            int left = 0, right = nums.length - 1;
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] > nums[right])
                    left = mid + 1;
                else if (nums[mid] < nums[right])
                    right = mid;
                else
                    right--;
            }
            return nums[left];
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] nums = {1,3,5};
        System.out.println(s.findMin(nums));
        int[] nums2 = {2,2,2,0,1}; 
        System.out.println(s.findMin(nums2));
    }
}

输出:

1
0

二分法中:

mid = (left + right) / 2;  存在相加后溢出可能,尽量要写成:

mid = left + (right - left) / 2; 


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/ 

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/6594.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Selenium被检测为爬虫,怎么屏蔽和绕过

01、Selenium 操作被屏蔽 使用selenium自动化网页时&#xff0c;有一定的概率会被目标网站识别&#xff0c;一旦被检测到&#xff0c;目标网站会拦截该客户端做出的网页操作。 比如淘宝和大众点评的登录页&#xff0c;当手工打开浏览器&#xff0c;输入用户名和密码时&#x…

Java SE 基础 (6) 第一个Java程序

开发环境已经搭建完毕&#xff0c;可以开发我们第一个Java程序了。 Java程序开发三步骤&#xff1a;编写、编译、运行。 编写Java源程序 public class HelloWord {public static void main(String[] args) {System.out.println("HelloWord!");} } 第一个 HelloWo…

蓝桥杯 路径

答案 import mathdef lcm(i,j):m math.gcd(i,j)return i*j//m n 2021 dp [float(inf)]*2022 dp[1] 0 for i in range(1,n1):for j in range(i1,i22):if j > n:breakdp[j] min(dp[j],dp[i]lcm(i,j)) print(dp[n]) 对dp[j] min(dp[j],dp[i]lcm(i,j))的解析&#xff1a;…

JAVASE 继承

文章目录继承1.为什么需要继承2.继承的概念3.继承的语法4.父类成员访问4.1 子类中访问父类的成员变量4.2 子类中访问父类的成员方法5 super关键字6.子类的构造方法7.super和this8.再谈初始化9.protected关键字10.继承方法11.final 关键字12.继承与组合继承 1.为什么需要继承 …

【C++笔试强训】第十天

选择题 解析&#xff1a;内联函数&#xff08;inline&#xff09;一般用于代码较少&#xff0c;代码块里面没有递归且频繁调用的函数&#xff0c;是一种以空间换时间&#xff08;不是指内存&#xff0c;而是指令变多编译出来的可执行程序会变大&#xff09;的做法。内联函数在预…

49天精通Java,第14天,Java泛型方法的定义和使用

目录一、基本介绍1、Java泛型的基本语法格式为&#xff1a;2、在使用泛型时&#xff0c;还需要注意以下几点&#xff1a;二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、…

第五章 Vite4+Vue3+Vtkjs 自定义按键组合

一、介绍 因为Vtk.js在按键和按键组合上默认就指定了对应的事件处理,但是我们在使用其他软件的时候可能已经养成了一种习惯,然后也希望使用Vtk.js的时候按键对应的事件也是一致的。比如右键是平移模型,或者说shift+鼠标右键是平移,不管是什么按键的组合,对应的事件是我们…

颠覆认知!“垃圾股”策略长期跑,10年翻100倍、近2年6倍,吊打茅指数!| 邢不行

这是一个非常简单的量化选股策略&#xff0c;它只用到了两个基础选股指标。 代表策略的橙色曲线2010年至今从1元涨到了112元&#xff0c;年化收益43%&#xff1b;在近两年大盘下跌的情况下&#xff0c;这个策略更是逆势翻了6倍。 这个量化策略究竟用了哪两个选股指标&#xf…

java TreeSet 和 TreeMap 源码解读

目录 一、前言 二、TreeSet详解 1.TreeSet简介 2.TreeSet的底层实现 0 准备工作 1 TreeSet构造器 2 匿名内部类实现接口的多态 3 TreeMap构造器 4 add方法 5 put方法和put方法 6 继续添加元素 7 修改比较器的比较原则 三、TreeMap详解 1.TreeMap简介 2.TreeMap的底层实现 0…

拥有良好的社交和友谊会使肠道微生物群更健康

谷禾健康 播种肠道&#xff0c;喂养心灵 在新冠疫情的影响下&#xff0c;我们的生活方式和社交模式都发生了很大的改变。随着社交距离的要求和封锁措施的实施&#xff0c;我们不得不放弃了很多与朋友和家人的互动&#xff0c;这给我们的身心健康带来了很大的影响。 然而&#x…

区块链学习笔记(3)BTC协议

假设有一个大家都信任的中心化机构想要发行数字货币。 该机构由用自己的私钥签名后后发行&#xff0c;任何人都可以通过公钥验证该货币是否为真。 买东西的时候&#xff0c;购买者可以将数字货币发送给卖方&#xff0c;卖方可以也可以通过公钥验证该货币为真后即可完成支付的过…

子网掩码和CIDR

CIDR是什么 网络标识相同的计算机必须同属于同一个链路。例如&#xff0c;架构B类IP网络时&#xff0c;理论上一个链路内允许6万5千多台计算机连接。然而&#xff0c;在实际网络架构当中&#xff0c;一般不会有在同一个链路上连接6万5千多台计算机的情况。因此&#xff0c;这种…

蓝桥杯刷题冲刺 | 倒计时7天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;最后一周&#xff0c;复习学过的知识&#xff0c;刷题冲刺&#x1f43e; 文章目录1.高精度除法2.扫地机器人3.数的范围4.A-B 数对1.高精度除法 题目 链接&#xff1a; 794. 高精度除法 - AcWing题…

Java对象内存布局

文章目录1、对象头对象标记Mark Word类元信息&#xff08;又叫类对象指针&#xff09;Class Pointer数组长度&#xff08;Array Length&#xff09;&#xff08;可选&#xff09;2、实例数据&#xff08;对象体&#xff09;3、对齐填充4、指针压缩5、再聊对象头的MarkWord6、JO…

Android ART虚拟机 Space类体系

前言 在ART虚拟机实现中&#xff0c;内存分配和释放的算法是封装在不同的Space中来完成的。而外部使用者只能借助Space及派生类的接口来完成内存的分配与释放。通过阅读这些Space的实现&#xff0c;可以看出ART虚拟机的一个重要的特点就是大量使用映射内存&#xff0c;相较于D…

思维导图软件哪个好?安利八款好用的思维导图软件

当你需要表达和整理复杂的想法、计划和项目时&#xff0c;思维导图软件可以是非常有用的工具。不同的思维导图软件有不同的功能和特点&#xff0c;选择适合自己的软件可以让你更高效地工作和学习。但是你了解思维导图软件哪个好呢&#xff1f;下面就给大家安利八款简单好用的思…

分享99个ASP影音娱乐源码,总有一款适合您

分享99个ASP影音娱乐源码&#xff0c;总有一款适合您 99个ASP影音娱乐源码下载链接&#xff1a;https://pan.baidu.com/s/1pYpAqFUX0xD8KR8GDRyiug?pwd3lja 提取码&#xff1a;3lja Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 我的博客地址&#xff1a;亚…

1Panel开源面板项目GitHub Star数量突破2,000!

截至2023年4月4日18:00&#xff0c;FIT2CLOUD飞致云旗下开源项目——1Panel开源Linux服务器运维管理面板GitHub Star数超过2,000个&#xff01;

IDE装上ChatGPT,一天开发一个系统

昨天白天在写代码&#xff0c;晚上看了一场直播&#xff0c;是两个技术的直播&#xff1a; 一个是技术总监&#xff0c;一个是号称Java之父的余**。 结果Java之父被技术总监吊打。然后匆匆下播。 技术这玩意&#xff0c;真的就是真的&#xff01; 白天我开发了一个系统&…

LeetCode.每日一题 2427. 公因子的数目

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…
最新文章