🥳每日一练-找到数组中最小的k个数-JS简易版

今天分享的内容是 2022 年考研的算法题:

现有 n 个数保存在一维数组 M 中,需要查找 M 中最小的 10 个数。简述算法思想,以及回答你算法的时间复杂度和空间复杂度

如果是你,你会怎么解决这个问题?


没有经验的小伙伴可能一时想不出来,但知道了怎么做之后就会恍然大悟,哦,原来这么简单。

可以准备一个长度为 10 的数组 array,数组array每一项都初始化为 Infinity 值,表示正无穷,也就是最大的数。然后遍历数组 M,如果遍历到的数组的值 value 大于array中最后一项,就将array最后一项删掉,并且把value按升序插入到array中。如此往复,直到遍历完整个 M,array中就是最小的 10 个数了

代码

javascript 复制代码
const data = [
	25, 74, 92, 2, 53, 41, 30, 58, 
  78, 91, 5, 92, 52, 85, 50, 6, 
  31, 41, 67, 29, 24, 58, 43, 57, 
  39, 78, 90, 45, 69, 94,
];

/**
 *
 * @param {number[]} array
 * @param {number} value
 */
const insertSort = (array, value) => {
	for (let i = 0; i < array.length; i++) {
		if (value > array[i]) continue;
		array.splice(i, 0, value);
		array.length--;
		return;
	}
};

const findMin = (data) => {
	const minArray = Array(5).fill(Infinity);
	for (let i = 0; i < data.length; i++) {
		if (data[i] < minArray[4]) {
			insertSort(minArray, data[i]);
			console.log(minArray);
		}
	}
	return minArray;
};

代码为了测试方便,没有准备这么多数据,只准备了 30 个数字,然后选出其中 5 个最小的数。

insertSort是一个升序插入的逻辑。从头至尾遍历到合适的位置插入 value,然后将数组的长度减一,以此达到删除数组最后一项的目的。(如果 C 语言实现会更啰嗦)

findMin就是找到数组中最小的 5 个数的函数了。刚开始,初始化一个长度为 5 的数组,数组中每个值都初始化为正无穷。然后从头至尾遍历 data,遍历的逻辑和上面说的一致,就不赘述了

在 27 行打印了 minArray,方便大家更直观地理解算法的过程

输出结果:

css 复制代码
[ 25, Infinity, Infinity, Infinity, Infinity ]
[ 25, 74, Infinity, Infinity, Infinity ]
[ 25, 74, 92, Infinity, Infinity ]
[ 2, 25, 74, 92, Infinity ]
[ 2, 25, 53, 74, 92 ]
[ 2, 25, 41, 53, 74 ]
[ 2, 25, 30, 41, 53 ]
[ 2, 5, 25, 30, 41 ]
[ 2, 5, 6, 25, 30 ]
[ 2, 5, 6, 25, 29 ]
[ 2, 5, 6, 24, 25 ]

很明显,最后 minArray 中留下来的数字,就是最小的 5 个数了

分析复杂度

时间复杂度

整个过程只遍历了 data 一遍,所以复杂度是 O(n)。虽然遍历的过程中有插入升序过程,但都是常数级别的。最坏的情况是每次遍历 data,都需要经历插入过程,假设插入过程的复杂度是 x,这个 x 是个常数。

那么最坏的复杂度就是 O(xn),化简之后还是O(n)

空间复杂度

算法实现过程,只借助了一个长度为 5 的数组,和 data 长度无关的量,所以空间复杂度是常数级别的 O(1)

常数什么意思,就是和输入量级无关的量,都可以视为常量。就算常量很大,有 10^3,甚至 10^6,只要不随输入量级变化而变化的量,都还是常量

总结

这篇文章分享了如何求数组中最小的 k 个数,算法的思想不难,难的是想到这个算法。后面复杂度分析也不难,有些算法基础就可以解决

你觉得这篇文章怎么样?喜欢就点赞+关注吧

相关推荐
叶子爱分享3 分钟前
经典排序算法之归并排序(Merge Sort)
算法·排序算法
珹洺9 分钟前
C++算法竞赛篇:DevC++ 如何进行debug调试
java·c++·算法
coding随想10 分钟前
掌控网页的魔法之书:JavaScript DOM的奇幻之旅
开发语言·javascript·ecmascript
然我38 分钟前
不用 Redux 也能全局状态管理?看我用 useReducer+Context 搞个 Todo 应用
前端·javascript·react.js
前端小巷子43 分钟前
Web 实时通信:从短轮询到 WebSocket
前端·javascript·面试
呆呆的小鳄鱼1 小时前
leetcode:冗余连接 II[并查集检查环][节点入度]
算法·leetcode·职场和发展
墨染点香1 小时前
LeetCode Hot100【6. Z 字形变换】
java·算法·leetcode
沧澜sincerely1 小时前
排序【各种题型+对应LeetCode习题练习】
算法·leetcode·排序算法
CQ_07121 小时前
自学力扣:最长连续序列
数据结构·算法·leetcode
弥彦_1 小时前
cf1925B&C
数据结构·算法