算法学习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,一经查实,立即删除!

相关文章

Xcode持续集成之道:自动化构建与部署的精粹

标题&#xff1a;Xcode持续集成之道&#xff1a;自动化构建与部署的精粹 在快节奏的软件开发中&#xff0c;持续集成&#xff08;Continuous Integration, CI&#xff09;是提升开发效率和软件质量的关键实践。Xcode作为苹果生态中的核心开发工具&#xff0c;提供了与多种持续…

上机算法刷题暑期篇(一) —— 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;损失函数模型评估指标 模型训练模型评估模型推理…

练习:随机点名器5

题目&#xff1a; TxT文件中事先准备好一些学生信息&#xff0c;每个学生的信息独占一行。,要求1&#xff1a;每次被点到的学生&#xff0c;再次被点到的概率在原先的基础上降低一半。 举例&#xff1a;80个学生&#xff0c;点名5次&#xff0c;每次都点到小A&#xff0c;概率…

网络规划设计师考试大纲

网络规划设计师考试大纲 网络规划设计师一年考一次&#xff0c;下半年开考&#xff0c;共有三个科目&#xff1a;综合知识、案例分析、论文。 科目包括&#xff1a; (1)网络规划与设计综合知识&#xff0c;考试时间为150分钟&#xff0c;笔试&#xff0c;选择题; (2)网络规划与…

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

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

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

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

【C++】CMake入门

CMake 是一个跨平台的构建系统生成工具&#xff0c;可以生成用于编译和链接应用程序的构建文件&#xff08;如 Makefile 或 Visual Studio 工程文件&#xff09;。 安装 CMake Windows 可以从 CMake官网 下载并安装 Windows 版本的 CMake。安装完成后&#xff0c;确保将 CMak…

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 自增 五、…

【web、DNS综合实验】

题目&#xff1a; 创建两个用户www.zhangsan.com 加密&#xff0c;www.lisi.com 目录&#xff1a;/www/zahngsan /www/lisi 主服务器做 dns web 从服务器做dns 在从服务器上能实现curl -k https://www.zhangsan.com ok&#xff0c;curl http://www.lisi.com ok 思路&#…

python爬虫学习(三十三天)---多线程上篇

hello&#xff0c;小伙伴们&#xff01;我是喔的嘛呀。今天我们来学习多线程方面的知识。 目录 一、了解多线程 &#xff08;1&#xff09;大概描述 &#xff08;2&#xff09;多线程爬虫的优势 &#xff08;3&#xff09;多线程爬虫的实现方式 &#xff08;4&#xff09…

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

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

【ZhangQian AI模型部署】目标检测、SAM、3D目标检测、旋转目标检测、人脸检测、检测分割、关键点、分割、深度估计、车牌识别、车道线识别

在模型部署落地&#xff08;主要部署到rk3588&#xff09;折腾了这么多年&#xff0c;把这些年折腾过的模型整理了一下&#xff0c;所有的流程说明、代码模型都完全开放的&#xff0c;欢迎交流学习。有的是为了项目、有的是为了学习、还有的是为了找点事做、有的完全是为了安抚…

字节码编程bytebuddy之实现抽象类并并添加自定义注解

写在前面 本文看下使用bytebuddy如何实现抽象类&#xff0c;并在子类中添加自定义注解。 1&#xff1a;代码 1.1&#xff1a;准备基础代码 类和方法注解 package com.dahuyou.bytebuddy.cc.mine;import java.lang.annotation.ElementType; import java.lang.annotation.Re…

Open3D 提取点云的重叠区域和非重叠区域

目录 一、概述 二、代码实现 三、实现效果 3.1原始点云 3.2处理后点云 一、概述 在点云处理中,提取点云的重叠区域和非重叠区域可以提供有价值的信息,用于多种应用。以下是详细解释及其作用: 配准质量评估:在多视角点云拼接或配准过程中,通过分析重叠区域,可…

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;本文将为您…

Memcached客户端库对决:解锁高性能缓存的钥匙

标题&#xff1a;Memcached客户端库对决&#xff1a;解锁高性能缓存的钥匙 Memcached作为一个高效的分布式内存缓存系统&#xff0c;在提升应用性能和扩展性方面发挥着关键作用。为了与Memcached服务器进行交互&#xff0c;开发者可以使用多种客户端库。这些库提供了丰富的API…

Spring中事件监听器

实现ApplicationListener接口 Configuration public class A48 {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(A48.class);context.getBean(MyService.class).doBusiness();context.close()…