算法学习day11

一、用最少数量的箭引爆气球()

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstartxend, 且满足  xstart ≤ x ≤ xend,则该气球会被 引爆 。

输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。

思路:按照左边界从小到大排列。

出现的情况:

1.points[i][0]>points[i-1][1]:第二个气球的左边界大于第一个气球的右边界(没有交集),此时射箭的数量就要++

2.points[i][0]<=points[i-1][1];此时这两个区域一定有交集,然后更新points[i][1]=Math.min(points[i][1],points[i-1][1]); 因为要看下一个区域和上两个区域有没有交集,就要取最小的那个边界,使都能满足

代码:

class Solution {public int findMinArrowShots(int[][] points) {/**对左边界或者右边界进行排序然后分情况 如果左边界大于上一个的右边界 直接result++直接 左边界小于等于上一个的右边界 那么更新右边界。然后 循环下一个*/int result=1;Arrays.sort(points,(a,b)->Integer.compare(a[0],b[0]));//使用Integer的内置方法不会溢出for(int i=1;i<points.length;i++){//如果左边界大于上一个的右边界if(points[i][0]>points[i-1][1]){result++;}else{points[i][1]=Math.min(points[i][1],points[i-1][1]);}}return result;}
}

二、无重叠区间(和气球类似)

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 

输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

思路:对集合进行左边界排序,如果intervals[i][0]>=intervals[i][1],说明没有重叠

;重叠之后处理的逻辑:将intervals[i][1]=Math.min(intervals[i][1],intervals[i-1][1]);result++

为了能使移除区间的数量是最小的,每次更新右边界为重叠的最小右边界,才能使删除的最小。

代码:

class Solution {public int eraseOverlapIntervals(int[][] intervals) {/**对区间进行 左边界排序然后挨个判断xxx*/Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));int result=0;for(int i=1;i<intervals.length;i++){if(intervals[i][0]>=intervals[i-1][1])continue;else{result++;intervals[i][1]=Math.min(intervals[i-1][1],intervals[i][1]);}}return result;}
}

三、合并区间


以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

思路:

先往集合里面放一个,如果第二个不重叠,那就放进去;

如果第二个重叠的话,就把更新后的数组放进去,然后把之前的删除掉;

代码:

class Solution {public int[][] merge(int[][] intervals) {/*** 继续对intervals 左边界排序* 如果出现重叠部分 就将左右边界更新 然后放到一个新的int[][]里面*/Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));ArrayList<int[]> list = new ArrayList<>();list.add(intervals[0]);// 先加一个for (int i = 1; i < intervals.length; i++) {if (intervals[i][0] > intervals[i - 1][1]) {list.add(intervals[i]);// 因为i-1已经添加了 如果i和i-1没有重叠的话 也加进去} else {intervals[i][0] = intervals[i - 1][0];// 更新一下最小边界intervals[i][1] = Math.max(intervals[i][1], intervals[i - 1][1]);list.remove(list.size() - 1);list.add(intervals[i]);}}int[][] newIntervals = new int[list.size()][2];int i = 0;for (int[] arr : list) {newIntervals[i++] = arr;}return newIntervals;}
}

如果遇到两个重叠的区间,那么左区间是intervals[i-1][0],因为是按照左区间的大小排序的

然后右边界为:Math.max(intervals[i-1][1],intervals[i-1][1])

四、划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表

输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。

思路: 使用哈希表记录每一个字母出现的最远位置。然后遍历字符串,每次更新范围中的最远下标位置(这里是使在start end这个区间里面,出现的字母只在这个区间里面出现),当i==maxDistance的时候,就将count加到list中,并且更新一下maxDistance

代码:

class Solution {public List<Integer> partitionLabels(String s) {Map<Character,Integer> map=new HashMap<>();for(int i=0;i<s.length();i++){map.put(s.charAt(i),i);//这里的位置是根据下标算的}List<Integer> result=new ArrayList<>();Integer maxDistance=map.get(s.charAt(0));int count=0;for(int i=0;i<s.length();i++){count++;if(map.get(s.charAt(i))>maxDistance){maxDistance=map.get(s.charAt(i));}if(i==maxDistance){result.add(count);count=0;if(i!=s.length()-1){maxDistance=map.get(s.charAt(i+1));}}}return result;}
}

五、单调递增的数字(贪心)

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

输入: n = 332
输出: 299

如何能找到一个数字<=n,并且每一位都是单调递增的。思路:首先从后往前遍历,当遇到i和i-1上的数字不是单调递增的就将i-1上的数字-1,然后flag=i,for循环结束之后,从flag开始,将后面的数字都改为9。

eg;332  2比3小,将 3--,然后flag记作3;然后往前一位遍历,2还是比3小,3--,flag=2;遍历完之后,从flag出发到最后一位,将值都置为9

代码:

class Solution {public int monotoneIncreasingDigits(int n) {String str=Integer.toString(n);char[] chars=str.toCharArray();int flag=str.length();for(int i=str.length()-1;i>0;i--){int n1=chars[i]-'0';int n2=chars[i-1]-'0';if(n1<n2){flag=i;chars[i-1]--;}}for(int i=flag;i<str.length();i++){chars[i]='9';}return Integer.parseInt(String.valueOf(chars));}
}

六、两数相加(链表)

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

思路:使用一个while循环 将两个节点的值加起来(考虑进位) 然后创建一个val为它的节点 等到遍历结束,还要考虑是否有进位。

代码:

class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {//虚拟头结点和临时指针ListNode pre=new ListNode(0);ListNode cur=pre;int carry=0;//进位//循环判断while(l1!=null||l2!=null){int num1=l1==null?0:l1.val;int num2=l2==null?0:l2.val;int num3=num1+num2+carry;carry=num3/10;int val=num3%10;cur.next=new ListNode(val);cur=cur.next;if(l1!=null)l1=l1.next;if(l2!=null)l2=l2.next;}//最后判断进位if(carry!=0)cur.next=new ListNode(carry);return pre.next;}
}

动态规划

动态规划题型:

基础题:斐波那契数字/爬楼梯

背包问题/打家劫舍/股票问题/子序列问题

解决动态规划需要掌握的几个点:

1.明白dp数组以及下标的含义
2.掌握递推公式
3.dp数组如何初始化
4.遍历顺序
5.打印数组

一、爬楼梯问题(入门/简单)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

思路:要求有多少种方法可以爬到楼顶?那就是在有多少种方法爬到楼顶下一层+爬到楼顶下下一层。eg:假设楼顶为6楼,那我爬向6楼只能从4楼或者5楼开始。因此

1.dp[i]含义:爬到i楼的有多少种方法

2.递推公式:dp[i]=dp[i-1]+dp[i-2];

3.如何初始化:dp[1]=1,dp[2]=2;

4.遍历顺序:从3开始遍历

二、使用最小花费爬楼梯(普通)

可以在下标为0/1的楼梯上选择是否要向上爬,一次可以爬一个楼梯或者两个楼梯,每一个下标对应一个花费,求爬到楼顶的最小花费。

输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。

注意:这里的楼顶是下标为3的地方

1.dp[i]:爬到第i层需要的价值

2.递推公式:dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);

3.初始化:dp[0],dp[1]=0;因为跳到台阶0,1是不需要花费的。

4.遍历顺序,从i=2开始。

代码:

    public int minCostClimbingStairs(int[] cost) {int[] dp=new int[cost.length+1];//dp数组的含义就是到达下标为i的最小花费dp[0]=0;dp[1]=0;for(int i=2;i<dp.length;i++){dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);}return dp[dp.length-1];}

三、不同路径

dp[][]:dp数组是一个二维数组,表示的是到(x,y)这个点一共有多少种路径

递推公式:dp[x][y]=dp[x-1][y]+dp[x][y-1];

初始化:最上面一行dp[0][i] 和最左边一行dp[i][0] 初始化都应该为1,因为只能往右和往下走,所以这些点都为1
遍历顺序:从(1,1)开始

    public int uniquePaths(int m, int n) {int[][] dp=new int[m][n];for(int i=0;i<m;i++){dp[i][0]=1;}for(int i=0;i<n;i++){dp[0][i]=1;}for(int i=1;i<m;i++){for(int j=1;j<n;j++){dp[i][j]=dp[i-1][j]+dp[i][j-1];}}return dp[m-1][n-1];}

四、不同路径II

在上一道题的基础上,有障碍物挡着。

dp五部曲和上一道题其实类似。不同的地方在于初始化\遍历时候的逻辑

初始化的时候先判断有没有障碍,如果有的话,后面就都走过不去了,直接break

遍历的时候,如果遇到有障碍的,直接将dp[i][j]置为0,

代码:

class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int x=obstacleGrid.length;int y=obstacleGrid[0].length;int[][] dp=new int[x][y];//初始化for(int i=0;i<x;i++){if(obstacleGrid[i][0]==1)break;dp[i][0]=1;}for(int j=0;j<y;j++){   if(obstacleGrid[0][j]==1)break;dp[0][j]=1; }for(int i=1;i<x;i++){for(int j=1;j<y;j++){if(obstacleGrid[i][j]==1)dp[i][j]=0;else{dp[i][j]=dp[i-1][j]+dp[i][j-1];}}}return dp[x-1][y-1];}   
}

五、整数拆分(不好理解)

1.dp[i]的含义:数值为i拆分成不同整数的积的最大值。

2.递推公式:dp[i]=Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));

对递推公式的解释:

一个数可以直接分成i,j(两个数)。这样乘积为j*(i-j);

还可以分成多个数,乘积为:j*dp[i-j];

那么在取最大值的时候,为什么还要比较dp[i]呢?:因为在递推公式推导的过程中,每次计算dp[i],取最大的而已。

3.dp的初始化:dp[0]=0;dp[1]=0;

4.遍历顺序

        for(int i=2;i<=n;i++){for(int j=1;j<i;j++){dp[i]=Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));}}

i从2->n(这里i也可以直接从3开始,因为dp[2]=2),然后将i依次分成 1 i-1|| 2,i-2。每次多更新dp[i]

代码:

class Solution {public int integerBreak(int n) {int[] dp=new int[n+1];dp[0]=dp[1]=0;for(int i=2;i<=n;i++){for(int j=1;j<i;j++){dp[i]=Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));}}printfDp(dp);return dp[n];}public void printfDp(int[] dp){for(int i=0;i<dp.length;i++){System.out.print(i+":"+dp[i]+" ");}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上机算法刷题暑期篇(一) —— AcWing 3692. 最长连续公共子序列(西电)

题目链接 AcWing 3692. 最长连续公共子序列 题目详情 题目解析 我们一看到题目,最长和连续子串&#xff0c;我们第一反应应该是什么?没错,就是dp,一般来说&#xff0c;子串问题常见的解法有两种&#xff1a; 双指针 dp 这道题无疑就是一道最常见的dp问题&#xff0c;而dp问…

昇思25天学习打卡营第11天 | FCN图像语义分割

昇思25天学习打卡营第11天 | FCN图像语义分割 文章目录 昇思25天学习打卡营第11天 | FCN图像语义分割FCN模型数据处理下载数据集创建训练集可视化训练集 网络构建网络结构张量操作 训练准备导入VGG-16部分预训练权重&#xff1a;损失函数模型评估指标 模型训练模型评估模型推理…

常见 Web漏洞分析与防范研究

前言&#xff1a; 在当今数字化时代&#xff0c;Web应用程序扮演着重要的角色&#xff0c;为我们提供了各种在线服务和功能。然而&#xff0c;这些应用程序往往面临着各种潜在的安全威胁&#xff0c;这些威胁可能会导致敏感信息泄露、系统瘫痪以及其他不良后果。 SQL注入漏洞 …

《昇思25天学习打卡营第16天|基于MindNLP+MusicGen生成自己的个性化音乐》

MindNLP 原理 MindNLP 是一个自然语言处理&#xff08;NLP&#xff09;框架&#xff0c;用于处理和分析文本数据。 文本预处理&#xff1a;包括去除噪声、分词、词性标注、命名实体识别等步骤&#xff0c;使文本数据格式化并准备好进行进一步分析。 特征提取&#xff1a;将文…

5 MySql

5 MySql 一、简介二、SQL语言2.1 导入外部SQL文件2.2 显示表结构2.3 与创建数据库相关的语句2.4 与表相关的语句2.5 操作表中的数据2.6 7种基本的sql查询 三、SQL的注意点3.1 与集合函数相关3.2 SQL语句的书写与执行过程 四、约束 constraint4.1 作用4.2 功能分类4.3 自增 五、…

头歌资源库(25)地图着色

一、 问题描述 任何平面区域图都可以用四种颜色着色&#xff0c;使相邻区域颜色互异。这就是四色定理。要求给定区域图&#xff0c;排出全部可能的着色方案。例如&#xff0c;区域图如下图所示&#xff1a; 要求用四种颜色着色。 则输入&#xff1a; 10 4 &#xff08;分别表示…

python-27-零基础自学python

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 统计文本单词数、 解决问题&#xff1a; gbk codec cant decode byte 0x9d in position 995: illegal multibyte sequence” 练习内容&#xff1a; 练习10-10&#xff1a;常见单词 …

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第二十六章 安装超级终端软件

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

短视频矩阵系统是什么?怎么搭建短视频矩阵系统?一文了解矩阵模式

在数字时代&#xff0c;短视频已成为信息传播的新宠&#xff0c;而短视频矩阵系统则是品牌和个人在短视频领域取得突破的重要工具。那么&#xff0c;短视频矩阵系统究竟是什么&#xff1f;如何搭建这样一个高效的系统&#xff1f;它又能够解决哪些问题呢&#xff1f;本文将为您…

C#绘制阻抗圆图初步

阻抗圆图&#xff0c;或者叫史密斯图&#xff0c;是无线电设计方面用的&#xff1b; 基本的阻抗圆图如下&#xff0c; 下面尝试用C#能不能画一下&#xff1b; 先在网上找一个画坐标的C#类&#xff0c;它的效果如下&#xff1b; 自己再增加一个函数&#xff0c;可以绘制中心在…

地址翻译过程(TLB-->页表-->Cache-->主存-->外存)

目录 1.地址结构 2.查找快表或页表&#xff1a;从虚拟地址--->物理地址 3.通过物理地址访问数据 设某系统满足以下条件&#xff1a; •有一个TLB与一个data Cache •存储器以字节为编址单位 •虚拟地址 14位 •物理地址 12位 •页面大小为 64B •TLB 为四路组相联&#x…

消防灭火设备软体水枪的使用方法

软体水枪是一款专为消防、应急救援等领域设计的灭火工具。其内胆采用大容量设计&#xff0c;能够储存足够的灭火剂&#xff0c;满足长时间、大范围的灭火需求。软体水枪是一种高效、便捷的灭火工具。它利用压力和流体力学原理&#xff0c;通过扣动扳机将储水箱中的水以高速喷射…

《金山 WPS AI 2.0:重塑办公未来的智能引擎》

AITOP100平台获悉&#xff0c;在 2024 世界人工智能大会这一科技盛宴上&#xff0c;金山办公以其前瞻性的视野和创新的技术&#xff0c;正式发布了 WPS AI 2.0&#xff0c;犹如一颗璀璨的星辰&#xff0c;照亮了智能办公的新征程&#xff0c;同时首次公开的金山政务办公模型 1.…

PyTorch | 加速模型训练的妙招

引言 提升机器学习模型的训练速度是每位机器学习工程师的共同追求。训练速度的提升意味着实验周期的缩短&#xff0c;进而加速产品的迭代过程。同时&#xff0c;这也表示在进行单一模型训练时&#xff0c;所需的资源将会减少。简而言之&#xff0c;我们追求的是效率。 熟悉 PyT…

SpringSecurity框架【认证】

目录 一. 快速入门 二. 认证 2.1 登陆校验流程 2.2 原理初探 2.3 解决问题 2.3.1 思路分析 2.3.2 准备工作 2.3.3 实现 2.3.3.1 数据库校验用户 2.3.3.2 密码加密存储 2.3.3.3 登录接口 2.3.3.4 认证过滤器 2.3.3.5 退出登录 Spring Security是Spring家族中的一个…

机器学习(V)--无监督学习(三)EM算法

EM算法 极大似然估计 极大似然估计&#xff1a;(maximum likelihood estimate, MLE) 是一种常用的模型参数估计方法。它假设观测样本出现的概率最大&#xff0c;也即样本联合概率&#xff08;也称似然函数&#xff09;取得最大值。 为求解方便&#xff0c;对样本联合概率取对…

华为HCIP Datacom H12-821 卷36

1.单选题 在PIM- SM中&#xff0c;以下关于RP 的描述&#xff0c;错误的是哪一选项? A、在PIM-SM中&#xff0c;组播数据流量不一定必须经过RP的转发。 B、对于一个组播组来说&#xff0c;可以同时有多个RP地址&#xff0c;提升网络可靠性。 C、组播网络中&#xff0c;可以…

【BUG】已解决:JsonMappingException

已解决&#xff1a;JsonMappingException 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 概述&#xff1a; 没有getter方法的实体的序列化&#xff0c;并解决Jackson引发的JsonMappingException异常。 默认情况下&#xff0c;Jackson 2只会处理公有字段或具有公有get…

Renesas R7FA8D1BH (Cortex®-M85) 控制DS18B20

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL配置 2.1 硬件接口电路 2.2 FSB配置DS18B20的IO 2.3 生成Keil工程文件 3 DS18B20驱动代码 3.1 DS18B20介绍 3.2 DS18B20驱动实现 3.2.1 IO状态定义 3.2.2 读IO状态函数 3.2.3…

OpenCV:python图像旋转,cv2.getRotationMatrix2D 和 cv2.warpAffine 函数

前言 仅供个人学习用&#xff0c;如果对各位朋友有参考价值&#xff0c;给个赞或者收藏吧 ^_^ 一. cv2.getRotationMatrix2D(center, angle, scale) 1.1 参数说明 parameters center&#xff1a;旋转中心坐标&#xff0c;是一个元组参数(col, row) angle&#xff1a;旋转角度…