🥳每日一练-找到数组中最小的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 个数,算法的思想不难,难的是想到这个算法。后面复杂度分析也不难,有些算法基础就可以解决

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

相关推荐
Tiandaren31 分钟前
Selenium 4 教程:自动化 WebDriver 管理与 Cookie 提取 || 用于解决chromedriver版本不匹配问题
selenium·测试工具·算法·自动化
岁忧2 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
chao_7892 小时前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
一斤代码2 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
3Katrina3 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
秋说4 小时前
【PTA数据结构 | C语言版】一元多项式求导
c语言·数据结构·算法
coderlin_4 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
Maybyy4 小时前
力扣61.旋转链表
算法·leetcode·链表
伍哥的传说4 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
我在北京coding4 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js