剑指 Offer(第2版)面试题 40:最小的 k 个数

2023-12-20

剑指 Offer(第2版)面试题 40:最小的 k 个数

题目来源: 53. 最小的 k 个数

解法1:排序

代码:

class Solution {
public:
    vector<int> getLeastNumbers_Solution(vector<int> input, int k) {
        if (input.empty() || k == 0)
            return {};
        sort(input.begin(), input.end());
        return vector<int>(input.begin(), input.begin() + k);
    }
};

复杂度分析:

时间复杂度:O(nlogn),其中 n 是数组 input 的长度。

空间复杂度:O(1)。

解法2:快速选择

运用快速排序的思想,每次快速选择会将一个数放置到正确的位置(即满足左边的数都比它小,右边的数都比它大),因此我们可以对原数组做 k 次快速选择。

但是这样做不能保证输出数组内元素按从小到大顺序排序。

代码:

class Solution
{
public:
	vector<int> getLeastNumbers_Solution(vector<int> input, int k)
	{
		vector<int> res;
		for (int i = 1; i <= k; i++)
			res.push_back(quick_select(input, 0, input.size() - 1, i));
		return res;
	}

	int quick_select(vector<int> &q, int l, int r, int k)
	{
		if (l >= r)
			return q[l];
		int i = l - 1, j = r + 1, x = q[l + r >> 1];
		while (i < j)
		{
			do
				i++;
			while (q[i] < x);
			do
				j--;
			while (q[j] > x);
			if (i < j)
				swap(q[i], q[j]);
		}
		if (k <= j - l + 1)
			return quick_select(q, l, j, k);
		else
			return quick_select(q, j + 1, r, k - (j - l + 1));
	}
};

复杂度分析:

时间复杂度:O(klogn),其中 n 是数组 input 的长度。一次快速选择的时间复杂度是 O(logn),进行 k 次。

空间复杂度:O(1)。

解法3:优先队列

维护一个大小为 k 的大顶堆,将数组元素都 push 进堆,当堆中的数大于 k 时弹出堆顶元素。

注意弹出堆顶的顺序是从大到小的 k 个数,要进行逆序操作。

代码:

class Solution {
public:
    vector<int> getLeastNumbers_Solution(vector<int> input, int k) {
        if (input.empty() || k == 0)
            return {};
        priority_queue<int> heap;
        for (int &x : input)
        {
            heap.push(x);
            if (heap.size() > k)
                heap.pop();
        }
        vector<int> ans;
        while (!heap.empty())
        {
            ans.push_back(heap.top());
            heap.pop();
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

时间复杂度:O(nlogk),其中 n 是数组 input 的长度。建堆的时间复杂度是O(logk),要进行 n 次建堆的操作。

空间复杂度:O(k)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

剑指 Offer(第2版)面试题 40:最小的 k 个数 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐