代码随想录算法训练营第三十六天| LeetCode435.无重叠区间、LeetCode763.划分字母区间、LeetCode56.合并区间

LeetCode 435 无重叠区间

题目链接:435. 无重叠区间 - 力扣(LeetCode)

【解题思路】

  • 需要先将数组按照左/右边界排序,这里按照左边界排序来解

  • 如果第i个区间的左边界大于等于i-1区间的右边界

【解题步骤】

  • 1.判断数组大小,如果等于0,则return 0;

  • 2.对数组的左边界进行排序

  • 3.定义一个result,初始化为0,记录重叠区间的数量

  • 3.遍历数组(i从1开始,因为比较的时候是i-1和i进行比较,从0开始会出现负数):

    • 如果当前元素左边界小于上一个气球的右边界:

      • result++

      • 当前元素右边界和上一个元素右边界取最小值更新当前元素的右边界

  • 5.return result

【代码部分】

class Solution {
	public int eraseOverlapIntervals(int[][] intervals) {
		Arrays.sort(intervals, (a,b)-> {
			return Integer.compare(a[0],b[0]);
		});
		int remove = 0;
		for(int i = 1; i < intervals.length; i++) {
			if(intervals[i-1][1] > intervals[i][0]) {
				remove++;
				intervals[i][1] = Math.min(intervals[i-1][1], intervals[i][1]);
			}
		}
		return remove;
	}
}

LeetCode 763 划分字母区间

题目链接:763. 划分字母区间 - 力扣(LeetCode)

【解题思路】

    将当前字母出现的最远位置记录下来,遍历收集到这个字母出现的最远位置,如果在遍历过程中收集到比我们当前“最远出现位置”更远的数组,则对我们收集元素的结束位置进行更新,直到收获。

【解题步骤】

  • 1.定义一个哈希数组,用来记录每个字母最远出现的位置

  • 2.遍历一遍字符串,记录每个字母的最远出现位置

  • 3.定义一个数组,存每个字符串的长度

  • 4.定义left和right分别记录当前区间的左右下标,计算当前区间的长度

  • 5.遍历字符串:

    • 不断更新右边界,取当前右边界与‘当前字母出现的最远位置’之间的最大值

    • 当遍历到最远处(i == right)

      • 将当前区间的长度放入结果集(right-left+1)

      • 更新left到当前位置的后一个位置(left = i +1)

【代码部分】

class Solution {
    public List<Integer> partitionLabels(String s) {
		List<Integer> result = new LinkedList<>();
		char[] chars = s.toCharArray();//将字符串放进数组里,方便遍历
		int [] edge = new int[26];
		for(int i = 0 ; i < chars.length ; i++){
			edge[chars[i] - 'a'] = i;
		}
		int left = 0;
		int right = 0;
		for(int i = 0; i < chars.length ; i++){
			right = Math.max(right,edge[chars[i] - 'a']);
			if(i == right){
				result.add(right - left + 1);
				left = i+1;
			}
		}
		return result;
    }
}

LeetCode 56 合并区间

题目链接:56. 合并区间 - 力扣(LeetCode)

【解题思路】

  • 将数组按照左边界排序,将相邻的区间挨在一起

  • 如果当前区间的左边界小于等于上一个区间的右边界,说明这两个区间一定重叠

    • 将两个区间合并后放入result结果集

  • 如果当前区间的左边界大于上一个区间的右边界,说明这两个区间没有重叠

    • 直接将区间放入result结果集

【解题步骤】

  • 1.定义一个二维数组result用来存放结果集

  • 2.如果区间的大小为0,说明区间是空,直接返回result

  • 3.将区间按照左边界由小到大进行排序

  • 4.将数组的第一个区间直接放入结果集

  • 5.遍历数组:

    • 如果当前遍历的区间的左边界小于等于上一个区间的右边界:

      • 因为我们的第一个区间已经放入结果集里,我们可以直接在结果集里进行修改,取上一个区间的操作就等价于从result结果集里取最后一个元素

      • 更新结果集里区间的右边界,即:取”当前区间的右边界和上一个区间的右边界“里的最大值

    • 如果当前遍历的区间的左边界大于上一个区间的右边界:

      • 将当前遍历的区间直接放入result数组里

  • 6.返回result数组

【代码部分】

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

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值