当前位置: 首页 > news >正文

Java每日精进·45天挑战·Day19

第一部分:移除数字以形成最小数的贪心算法实现

在编程的世界里,我们经常遇到需要对字符串表示的数字进行操作的问题。今天,我们要深入探讨一个具体的挑战:给定一个以字符串形式表示的非负整数 num 和一个整数 k,我们的任务是移除 k 位数字,以使得剩下的数字尽可能小。最终,我们需要返回这个最小的数字(仍然以字符串形式)。

问题背景

这个问题看似简单,实则充满了挑战。我们需要仔细思考如何高效地移除数字,以确保剩下的数字最小。为了更好地理解这个问题,让我们先来看几个示例:

  • 输入:num = "1432219"k = 3
    输出:"1219"
    解释:移除数字 4、3 和 2 后,我们得到新的最小数字 "1219"。

  • 输入:num = "10200"k = 1
    输出:"200"
    解释:移除首位的 1 后,剩下的数字为 "200"。注意,输出不能有任何前导零,除非整个数字就是零。

  • 输入:num = "10"k = 2
    输出:"0"
    解释:移除所有数字后,结果为空,因此返回 "0"。

贪心算法思路

为了解决这个问题,我们可以采用贪心算法。贪心算法在每一步选择中都采取最好或最优(即最有利)的选择,从而希望能够导致结果是全局最好或最优的算法。

在这个问题中,我们的每一步选择是:尽可能让高位数字小。具体思路如下:

  1. 使用一个栈来维护当前构建的最小数字。栈的特点是后进先出(LIFO),非常适合用于这种需要“回溯”的场景。

  2. 遍历输入字符串的每一个字符:

    • 如果栈不为空,当前字符比栈顶字符小,且还有移除次数 k 大于 0,那么我们可以弹出栈顶字符,并将 k 减 1。这样做的目的是确保高位数字尽可能小。
    • 将当前字符压入栈中。
  3. 遍历结束后,如果移除次数 k 仍然大于 0,说明还需要从栈顶继续移除字符,直到 k 为 0。

  4. 构建结果字符串并去除前导零。将栈中的字符依次弹出并拼接成字符串。注意要去除前导零,除非整个数字就是零。

  5. 处理边界情况。如果最终结果为空字符串,则返回 "0"。

Java 实现

下面,我们将上述思路转化为 Java 代码:

import java.util.Stack;public class RemoveKDigitsBlog {public String removeKDigits(String num, int k) {Stack<Character> stack = new Stack<>();// 遍历输入字符串的每一个字符for (char digit : num.toCharArray()) {// 如果栈不为空,当前字符比栈顶字符小,且还有移除次数 k 大于 0while (!stack.isEmpty() && stack.peek() > digit && k > 0) {stack.pop(); // 弹出栈顶字符k--; // 移除次数减 1}stack.push(digit); // 将当前字符压入栈中}// 如果还有剩余的 k 需要移除,继续从栈顶移除while (k > 0) {stack.pop();k--;}// 构建结果字符串,并去除前导零StringBuilder result = new StringBuilder();while (!stack.isEmpty()) {char digit = stack.pop();if (!(result.length() == 0 && digit == '0')) {result.insert(0, digit);}}// 如果结果为空,则返回 "0"return result.length() == 0 ? "0" : result.toString();}// 为了方便测试,我们在这里添加了一个 main 方法public static void main(String[] args) {RemoveKDigitsBlog solution = new RemoveKDigitsBlog();System.out.println(solution.removeKDigits("1432219", 3)); // 输出 "1219"System.out.println(solution.removeKDigits("10200", 1));   // 输出 "200"System.out.println(solution.removeKDigits("10", 2));      // 输出 "0"// 可以添加更多测试用例来验证算法的正确性}
}
总结

通过贪心算法,我们能够高效地解决这个问题。该算法的时间复杂度是 O(n),其中 n 是输入字符串的长度。这个算法不仅简单易懂,而且在实际应用中表现良好。

希望这篇博客能够帮助你更好地理解这个问题及其解决方案!如果你有任何疑问或建议,请随时在评论区留言。编程的世界充满了无限可能,让我们一起探索、学习和成长!

第二部分:最大和的连续子数组--动态规划与分治法的探索

在算法的世界里,寻找最大和的连续子数组是一个经典的问题,它有多种解法,每种解法都有其独特的魅力和应用场景。今天,我们将深入探讨两种解法:动态规划和分治法,并通过Java代码实现它们。

问题背景

给定一个整数数组 nums,我们需要找到一个具有最大和的连续子数组(子数组至少包含一个元素),并返回其最大和。连续子数组是数组中的一个连续部分。

动态规划解法

动态规划是一种通过将问题分解为子问题来求解的方法。在这个问题中,我们可以定义一个数组 dp,其中 dp[i] 表示以 nums[i] 结尾的连续子数组的最大和。状态转移方程为:

dp[i] = max(nums[i], dp[i-1] + nums[i])

这意味着,对于每个元素 nums[i],我们要么选择它作为一个新的子数组的起点(即 nums[i] 本身),要么将它加到之前的子数组上(即 dp[i-1] + nums[i])。我们取这两种选择中的较大值作为 dp[i] 的值。

最终,我们遍历 dp 数组,找到其中的最大值,即为所求的最大和的连续子数组的和。

Java 实现(动态规划)
public class MaxSubArraySum {public int maxSubArray(int[] nums) {int n = nums.length;int[] dp = new int[n];dp[0] = nums[0];int maxSum = dp[0];for (int i = 1; i < n; i++) {dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);maxSum = Math.max(maxSum, dp[i]);}return maxSum;}public static void main(String[] args) {MaxSubArraySum solution = new MaxSubArraySum();int[] nums1 = {-2, 1, -3, 4, -1, 2, 1, -5, 4};System.out.println(solution.maxSubArray(nums1)); // 输出 6int[] nums2 = {1};System.out.println(solution.maxSubArray(nums2)); // 输出 1int[] nums3 = {5, 4, -1, 7, 8};System.out.println(solution.maxSubArray(nums3)); // 输出 23}
}

 

分治法解法

分治法是一种将问题递归地分解为更小的问题,然后合并这些更小的问题的解决方案来得到原问题的解决方案的方法。在这个问题中,我们可以将数组 nums 分为左右两部分,然后分别求解左右两部分的最大和的连续子数组。同时,我们还需要考虑跨越左右两部分的子数组,即最大和的连续子数组可能从左边开始,穿过中间点,然后结束在右边。

对于跨越左右两部分的子数组,我们可以通过在左边部分找到从右往左的最大和的子数组,在右边部分找到从左往右的最大和的子数组,然后将它们相加得到跨越部分的最大和。最后,我们将左右两部分的最大和以及跨越部分的最大和进行比较,取其中的最大值作为当前问题的解。

Java 实现(分治法)
public class MaxSubArraySumDivideAndConquer {public int maxSubArray(int[] nums) {return maxSubArrayHelper(nums, 0, nums.length - 1);}private int maxSubArrayHelper(int[] nums, int left, int right) {if (left == right) {return nums[left];}int mid = left + (right - left) / 2;int leftSum = maxSubArrayHelper(nums, left, mid);int rightSum = maxSubArrayHelper(nums, mid + 1, right);int crossSum = findMaxCrossingSubarray(nums, left, mid, right);return Math.max(Math.max(leftSum, rightSum), crossSum);}private int findMaxCrossingSubarray(int[] nums, int left, int mid, int right) {int leftSum = Integer.MIN_VALUE;int sum = 0;for (int i = mid; i >= left; i--) {sum += nums[i];leftSum = Math.max(leftSum, sum);}int rightSum = Integer.MIN_VALUE;sum = 0;for (int i = mid + 1; i <= right; i++) {sum += nums[i];rightSum = Math.max(rightSum, sum);}return leftSum + rightSum;}public static void main(String[] args) {MaxSubArraySumDivideAndConquer solution = new MaxSubArraySumDivideAndConquer();int[] nums1 = {-2, 1, -3, 4, -1, 2, 1, -5, 4};System.out.println(solution.maxSubArray(nums1)); // 输出 6int[] nums2 = {1};System.out.println(solution.maxSubArray(nums2)); // 输出 1int[] nums3 = {5, 4, -1, 7, 8};System.out.println(solution.maxSubArray(nums3)); // 输出 23}
}

 

总结

通过动态规划和分治法,我们能够高效地解决寻找最大和的连续子数组的问题。动态规划通过记录以当前元素结尾的子数组的最大和来逐步构建解决方案,而分治法则通过递归地将问题分解为更小的问题来求解。这两种方法都有其独特的优势和适用场景,我们可以根据具体问题的规模和特点来选择合适的方法。

希望这篇博客能够帮助你更好地理解这个问题及其两种解法!如果你有任何疑问或建议,请随时在评论区留言。

相关文章:

Java每日精进·45天挑战·Day19

第一部分&#xff1a;移除数字以形成最小数的贪心算法实现 在编程的世界里&#xff0c;我们经常遇到需要对字符串表示的数字进行操作的问题。今天&#xff0c;我们要深入探讨一个具体的挑战&#xff1a;给定一个以字符串形式表示的非负整数 num 和一个整数 k&#xff0c;我们的…...

区块链的交易管理和共识机制

区块链的交易管理和共识机制是其核心功能&#xff0c;以下为你详细介绍它们的实现方式&#xff1a; 交易管理的实现 交易发起 • 用户使用钱包软件创建一笔交易&#xff0c;该交易包含发送方地址、接收方地址、转账金额等关键信息。同时&#xff0c;发送方会使用自己的私钥对…...

最新国内 ChatGPT Plus/Pro 获取教程

最后更新版本&#xff1a;20250202 教程介绍&#xff1a; 本文将详细介绍如何快速获取一张虚拟信用卡&#xff0c;并通过该卡来获取ChatGPT Plus和ChatGPT Pro。 # 教程全程约15分钟开通ChatGPT Plus会员帐号前准备工作 一个尚未升级的ChatGPT帐号&#xff01;一张虚拟信用卡…...

Apollo 9.0 速度动态规划决策算法 – path time heuristic optimizer

文章目录 1. 动态规划2. 采样3. 代价函数3.1 障碍物代价3.2 距离终点代价3.3 速度代价3.4 加速度代价3.5 jerk代价 4. 回溯 这一章将来讲解速度决策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的内容。Apollo 9.0使用动态规划算法进行速度决策&#xff0c;从类名…...

Apache Iceberg 与 Apache Hudi:数据湖领域的双雄对决

在数据存储和处理不断发展的领域中&#xff0c;数据湖仓的概念已经崭露头角&#xff0c;成为了一种变革性的力量。数据湖仓结合了数据仓库和数据湖的最佳元素&#xff0c;提供了一个统一的平台&#xff0c;支持数据科学、商业智能、人工智能/机器学习以及临时报告等多种关键功能…...

【LeetCode Hot100 普通数组】最大子数组和、合并区间、旋转数组、除自身以外数组的乘积、缺失的第一个正整数

普通数组 1. 最大子数组和&#xff08;Maximum Subarray&#xff09;解题思路动态规划的优化解法&#xff08;Kadane 算法&#xff09;核心思想 代码解析 2. 合并区间&#xff08;Merge Intervals&#xff09;解题思路代码实现 3. 旋转数组&#xff08;Rotate Array&#xff09…...

共享存储-一步一步部署ceph分布式文件系统

一、Ceph 简介 Ceph 是一个开源的分布式文件系统。因为它还支持块存储、对象存储&#xff0c;所以很自 然的被用做云计算框架 openstack 或 cloudstack 整个存储后端。当然也可以单独作 为存储&#xff0c;例如部署一套集群作为对象存储、SAN 存储、NAS 存储等。 二、ceph 支…...

19.Python实战:实现对博客文章的点赞系统

Flask博客点赞系统 一个基于Flask的简单博客系统&#xff0c;具有文章展示和点赞功能。系统使用MySQL存储数据&#xff0c;支持文章展示、点赞/取消点赞等功能。 功能特点 文章列表展示文章详情查看&#xff08;模态框展示&#xff09;点赞/取消点赞功能&#xff08;每个IP只…...

【stm32】定时器输出PWM波形(hal库)

一. PWM基本原理 PWM是一种通过调节信号的占空比&#xff08;Duty Cycle&#xff09;来控制输出平均电压的技术。占空比是指高电平时间与整个周期时间的比值。例如&#xff1a; - 占空比为50%时&#xff0c;输出平均电压为电源电压的一半。 - 占空比为100%时&#xff0c;输出始…...

当Ollama遇上划词翻译:我的Windows本地AI服务搭建日记

&#x1f680; 实现Windows本地大模型翻译服务 - 基于OllamaFlask的划词翻译实践 &#x1f6e0;️ 步骤概要1️⃣ python 环境准备2️⃣ Ollama 安装3️⃣ 一个 Flask 服务4️⃣ Windows 服务化封装5️⃣ 测试本地接口6️⃣ 配置划词翻译自定义翻译源7️⃣ 效果展示8️⃣ debug…...

Linux上Elasticsearch 集群部署指南

Es 集群部署 Es 集群部署 Es 集群部署 准备好三台服务器。示例使用&#xff1a;110.0.5.141/142/143 1、es用户和用户组创建&#xff0c;使用root账号 groupadd esuseradd -g es es2、将es安装包和ik分词器上传到&#xff1a;/home/es/目录下&#xff08;任意目录都行&#…...

字节Trae使用感想(后端)

前言 昨天分享了字节哥的Trae从0到1创作模式构建一个vue前端项目&#xff0c;今天又来试试她的后端项目能力。不是我舔&#xff0c;不得不说确实不错。可惜现在曾经没有好好学习&#xff0c;进不了字节。既然进不了字节&#xff0c;那我就用字节哥的产品吧。 后面有惊喜…...

国产编辑器EverEdit - 二进制模式下观察Window/Linux/MacOs换行符差异

1 换行符格式 1.1 应用场景 稍微了解计算机历史的人都知道&#xff0c; 计算机3大操作系统&#xff1a; Windows、Linux/Unix、MacOS&#xff0c;这3大系统对文本换行的定义各不相同&#xff0c;且互不相让&#xff0c;导致在文件的兼容性方面存在一些问题&#xff0c;比如它们…...

文心一言4月起全面免费,6月底开源新模型:AI竞争进入新阶段?

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、文心一言免费化的背后&#xff1a;AI成本与应用的双重驱动1️⃣成本下降&#xff0c;推动文心一言普及2…...

解锁机器学习算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…...

如何使用Three.js制作3D月球与星空效果

目录 1. 基本设置2. 创建星空效果3. 创建月球模型4. 添加中文3D文字5. 光照与相机配置6. 动画与控制7. 响应式布局8. 结语 在本文中&#xff0c;我们将一起学习如何利用Three.js实现一个3D月球与星空的效果&#xff0c;并添加一些有趣的元素&#xff0c;比如中文3D文字和互动功…...

SQL语句语法

SQL数据库的结构为 库database 表table 段segment 行row 列column 或field SQL 语句主要分为以下几类&#xff1a; 数据定义语言&#xff08;DDL&#xff09;&#xff1a;用于定义数据库对象&#xff0c;如数据库、表、视图、索引等。数据操作语言&#xff08;DML&#xff09;&…...

github上文件过大无法推送问题

GitHub 对文件大小有限制&#xff0c;超过 100 MB 的文件无法直接推送到仓库中。 解决思路&#xff1a; 使用 Git Large File Storage (Git LFS) 来管理大文件不上传对应的大文件 使用Git LFS&#xff1a; 1. 安装 Git LFS 首先&#xff0c;你需要安装 Git LFS。可以按照以…...

微信小程序的请求函数封装(ts版本,uniapp开发)

主要封装函数代码&#xff1a; interface HttpOptions {url: string;method?: string;headers?: { [key: string]: string };data?: any; }class Http {private timeout: number;private baseUrl: string;public constructor() { this.timeout 60 * 1000;this.baseUrl ht…...

Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件

步骤1 开始通过 WSL 使用 VS Code | Microsoft Learn 点击远程开发扩展包。 步骤2 Remote Development - Visual Studio Marketplace 点击install&#xff0c; 允许打开Visual Studio Code。 步骤3 共有4项&#xff0c;一齐安装。 步骤4 在WSL Linux(Ubuntu)中&#xf…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...