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

代码随想录打卡|Day27(合并区间、单调递增的数字、监控二叉树)

贪心算法 Part05

合并区间

力扣题目链接
代码随想录链接
视频讲解链接

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

思路:对于这道题目,我们只需要按照每个区间的左边界进行从小到大排序,随后依次遍历每个区间,获取他们的范围,将范围有重叠的区间合并(取重叠区间的最小做区间和最大右区间的值),并将合并后得出的每个区间的范围重新记录,最后输出即可。

代码如下:

class Solution {public int[][] merge(int[][] intervals) {// Arrays.sort(intervals,(a,b) -> a[0] - b[0]);Arrays.sort(intervals,(a,b) -> Integer.compare(a[0],b[0]));int start = intervals[0][0] ;int end = intervals[0][1];List<int[]> res = new LinkedList<>();for(int i = 1 ; i < intervals.length ; i++){if(intervals[i][0] <= end){start = Math.min(start , intervals[i][0]);end = Math.max(end , intervals[i][1]);}else{res.add(new int[]{start , end});start = intervals[i][0];end = intervals[i][1];}}res.add(new int[]{start , end});return res.toArray(new int[res.size()][]);}
}

代码随想录代码:

/**
时间复杂度 : O(NlogN) 排序需要O(NlogN)
空间复杂度 : O(logN)  java 的内置排序是快速排序 需要 O(logN)空间*/
class Solution {public int[][] merge(int[][] intervals) {List<int[]> res = new LinkedList<>();//按照左边界排序Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));//initial start 是最小左边界int start = intervals[0][0];int rightmostRightBound = intervals[0][1];for (int i = 1; i < intervals.length; i++) {//如果左边界大于最大右边界if (intervals[i][0] > rightmostRightBound) {//加入区间 并且更新startres.add(new int[]{start, rightmostRightBound});start = intervals[i][0];rightmostRightBound = intervals[i][1];} else {//更新最大右边界rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);}}res.add(new int[]{start, rightmostRightBound});return res.toArray(new int[res.size()][]);}
}

单调递增的数字

力扣题目链接
代码随想录链接
视频讲解链接

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

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

在这里插入图片描述

思路:将数组转换成为字符串再转换为数组,从尾到头判断两个相邻数字的大小是否满足递增,若不满足,前一个数字减一,后一个数字变成9.

代码如下:

class Solution {public int monotoneIncreasingDigits(int n) {String str = String.valueOf(n);char[] strArray = str.toCharArray();// 记录需要变成9的数字开始下标int index = strArray.length;for(int i = strArray.length - 2; i >= 0 ; i--){if(strArray[i] > strArray[i + 1]){strArray[i] --;index = i + 1;}}for(int i = index ; i < strArray.length ; i++)strArray[i] = '9';return Integer.parseInt(String.valueOf(strArray));}
}

另一种方法(创建了String数组,多次使用Integer.parseInt了方法,这导致不管是耗时还是空间占用都非常高,用时12ms)

class Solution {public int monotoneIncreasingDigits(int N) {String[] strings = (N + "").split("");int start = strings.length;for (int i = strings.length - 1; i > 0; i--) {if (Integer.parseInt(strings[i]) < Integer.parseInt(strings[i - 1])) {strings[i - 1] = (Integer.parseInt(strings[i - 1]) - 1) + "";start = i;}}for (int i = start; i < strings.length; i++) {strings[i] = "9";}return Integer.parseInt(String.join("",strings));}
}

监控二叉树

力扣题目链接
代码随想录链接
视频讲解链接

题目描述:给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。
在这里插入图片描述
思路:对于二叉树的题目,使用递归解决问题的时候需要考虑是应该使用前中后哪一种顺序。在本题目之中,我们需要使用最少数量的摄像头覆盖二叉树的所有节点,那么我们就一定不能在叶子节点部署摄像头,所以我们需要隔层安放摄像头。
基于此,我们对每个节点定义三种状态:
0:该节点没有被摄像头覆盖
1:该节点安放摄像头
2:该节点被摄像头覆盖

所以,对于一个非叶子节点,他的状态会存在三种:
在这里插入图片描述

1.该节点的两个叶子节点被覆盖,该节点就应该先赋值为0;
2.该节点的左节点或者右节点为0,则说明该节点必须安装摄像头。
3.该节点的至少一个叶子节点安装摄像头,则该节点应该被标记为2(被覆盖)。

此外,递归结束之后,root节点的值可能还会出现为0的情况,需要单独处理,若递归函数返回值为0,则摄像头的数量应该+1;

代码如下:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {int result = 0;public int minCameraCover(TreeNode root) {// if(root.left == null && root.right == null) return 1;// 还会存在root节点为0的情况,因此,需要再次判断if(minCameraCounter(root)==0) result++;return result;}/**节点的状态值:0 表示无覆盖1 表示 有摄像头2 表示有覆盖后序遍历,根据左右节点的情况,来判读 自己的状态*/// 1.确定递归函数的返回类型和传入参数类型private int minCameraCounter(TreeNode node){// 确定递归函数的结束条件// 1.当节点为叶子节点的时候,我们应该将他的值赋值为2if(node == null) return 2;// leftint left = minCameraCounter(node.left);// rightint right = minCameraCounter(node.right);// 情况1:当节点的左右孩子的值均为2,则证明节点不用部署摄像头if(left == 2 && right == 2){ return 0;}// 情况2:当节点的左孩子或右孩子的值为0的时候,就代表该节点应该部署摄像头if(left == 0 || right == 0){result++;return 1;}// 情况3:当节点的左右孩子至少存在一个摄像头的时候,那么该节点的就应该是被覆盖了else{return 2;}}
}

相关文章:

  • 河道流量监测:雷达流量计与多普勒流量计的优劣势与技术特点分析
  • 【C语言】全局变量、静态本地变量
  • 常见的几种分块策略,每种策略都有适用场景和优缺点
  • 华为L410上制作内网镜像模板:搭建Apache服务器并上传离线WeChat包
  • Linux-05 半个月崩了三次 ubuntu 系统记录
  • 基于STM32、HAL库的ADS1256IDBR模数转换器ADC驱动程序设计
  • 常见的6种外挂获取执行时机方法介绍
  • 安全编排自动化与响应(SOAR):从事件响应到智能编排的技术实践
  • 常见游戏引擎介绍与对比
  • Linux的基础指令
  • Exposure Adjusted Incidence Rate (EAIR) 暴露调整发病率:精准量化疾病风险
  • 关于hbaseRegion和hbaseRowKey的一些处理
  • linux ptrace 图文详解(七) gdb、strace跟踪系统调用
  • Python解析地址中省市区街道
  • Codeforces Round 1020 (Div. 3) A-D
  • 【高频考点精讲】ES6 String的新增方法,处理字符串更方便了
  • Unreal制作角色冲锋时冲击波效果
  • 论文学习:《聚类矩阵正则化指导的层次图池化》
  • 数学基础 -- 欧拉恒等式的魅力:让复数旋转起来!
  • 通信算法之273 : 循环自相关函数和自相关函数
  • 鲁迅先生儿媳、周海婴先生夫人马新云女士逝世,享年94岁
  • 国台办:提醒相关人员不要假借去第三地名义绕道赴台
  • 俄罗斯纪念卫国战争胜利80周年阅兵式首次彩排在莫斯科举行
  • 书业观察|一本书的颜值革命:从毛边皮面到爆火的刷边书
  • 卸任兰大校长后,严纯华院士重返北大作报告
  • 葡萄牙总理:未来几小时内将全面恢复供电