🥳前端算法面试--贪心算法只求解多区间--说几句心里话吧

今天分享的内容是如何用贪心算法,在固定范围内找到更多子区间

问题描述

现在有多个子区间,区间的范围是从 n 到 m,请在这些区间中,找出最多不相互覆盖的子区间

javascript 复制代码
const data = [
	[6, 8],
	[2, 4],
	[3, 5],
	[1, 5],
	[5, 9],
	[8, 10],
];

data 是一个二维数组,其中可以找到的最多,不冲突的子区间是:

javascript 复制代码
const spaces = [ [ 2, 4 ], [ 6, 8 ], [ 8, 10 ] ];

思路分析

寻找最多区间的问题,就要请出我们今天的主角了--贪心算法

贪心算法是一种在许多情况下都可以有效解决问题的算法。它的基本思想是每次选择当前最优的解,即局部最优解。贪心算法的求解过程是每次选择当前最优的解,直到满足终止条件。

贪心顾名思义,就是只顾眼前的利益,只顾着眼前能看见的最优。虽然不好听,但是解决当前的问题却再合适不过了。

对于当前的问题,可以先将各个区间按照左端点排序,然后找下一个区间,要求和当前区间不相互覆盖,并且区间范围最小。为什么?因为这样可以使剩下的空白区间范围足够大,可以容纳更多的子区间。优先最短,构成局部最优,这就是贪心思想。

说是这么说,看起来挺简单的,但是按照上面的描述来写代码却不容易。可以换个思路:

对区间的右端点进行升序排序,每加入一个线段,然后选择后面一个或者多个右端点相同的区间,然后在选中区间内选择左端点最大的那一条,也就是区间最小的。如果加入以后不会跟之前的区间不会相互覆盖,那么就加入,否则就继续判断后面的区间

很简单吧,来看看代码咋写

代码实现

javascript 复制代码
//倒序插入
const insertOrder = (array, value) => {
	for (let i = 0; i < array.length; i++) {
		if (value[0] >= array[i][0]) {
			array[i].splice(i, 0, value);
			return;
		}
	}
	array.push(value);
};

// 找到最多的区间
// table是区间表
const findManySpace = (table) => {
	table = table.sort((a, b) => a[1] - b[1]);

	const res = [];
	for (let i = 0; i < table.length; i++) {
		let tempArray = [];
		let j = i;
		// 找到相同右端点的区间
		for (; j < table.length; j++) {
			// 倒序插入
			if (table[i][1] == table[j][1]) insertOrder(tempArray, table[j]);
			else break;
		}
		i = j - 1;

		// res初始可能为空,就不考虑区间覆盖的问题
		if (res.length == 0) {
			res.push(tempArray[0]);
			continue;
		}

		// 遍历,找到第一个不覆盖的区间
		for (let i = 0; i < tempArray.length; i++) {
			if (tempArray[i][0] >= res[res.length - 1][1]) {
				res.push(tempArray[i]);
				break;
			}
		}
	}

	console.log(res);
};

代码的思路,也就入上面描述中所讲的一样,代码就不做详细解释了。

其中有两个需要注意的地方,提一下

  1. 为了能够快速地在相同右端点的区间中,找到最大左端点的区间,可以采用有序插入的方式,这样就不用再对 tempArray 排序了
  2. 在找到若干个相同右端点的区间后,需要修改 i 的值,表示 i 前面的区间已经被考虑过了。下一轮循环直接从 i 后面的区间开始

测试代码

javascript 复制代码
findManySpace(data);
// [ [ 2, 4 ], [ 6, 8 ], [ 8, 10 ] ]

输出正确

总结

本篇文章分享的是一道非常经典的区间求解问题,主要采用的策略是贪心算法。思路很简单,代码也很简单,难的是,如果不看答案之前,这道题根本做不出来....我在说我自己

说句题外话,写完这篇文章,我已经在算法和数据结构专题上分享了 50 余篇文章了,感觉仍在基础打转。数据结构是基础不假,但会了数据结构绝对不代表会算法,算法是解题方法,像数学题目一样,知识是知识,题目是题目,学会了知识,不代表会做题目。而且题目的解法,技巧是另一个层面的东西。

到现在,本专栏分享的数据结构涵盖了大学本科要求的所有数据,从数组,链表,到二叉树,二叉搜索树,多叉树,AVL 平衡树,B 树,(红黑树暂时没有), 图,集合,堆,hash表,分享的算法有排序算法,贪心算法,回溯算法,动态规划,对于浩如烟海的算法问题,这点很不够看。

刚去力扣试了试身手,结果被杀得卸甲归田...我还是在说我自己

难道要进入做一道会一道,不做就不会的怪圈么...给自己打了一个问号❓

题外话说完了,有问题可以评论区留言哦。我每天都会分享一篇算法小练习,喜欢就点赞+关注吧

相关推荐
怕浪猫1 小时前
GEO 优化到底是什么?AI时代内容创作者必须懂的新技能
算法·面试·github
朝朝辞暮i2 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Evand J3 小时前
【MATLAB例程】三维RRT+APF避障路径规划与到达角(AOA)定位算法|三维路径优化与定位仿真例程
算法·matlab·路径规划·代码·定位·rrt·aoa
weixin_307779134 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
朝朝辞暮i5 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
沙漠之主5 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
hasty5 小时前
不上传新包,也能改变用户拿到的版本:npm dist-tag 的 OIDC 权限治理
前端·npm·node.js
朝朝辞暮i5 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
Godspeed Zhao5 小时前
现代智能雷达技术14——算法(0)
线性代数·算法·雷达
Csvn6 小时前
diff 算法(虚拟 DOM Reconciliation)
前端