和最小的K个数对

简介: 和最小的K个数对

研究了一个需要使用堆的题目,即和最小的k个数对

给定两个递增排序的整数数组,从两个数组中各取一个数字u和v组成一个数对(u, v),请找出和最小的k个数对。例如,输入两个数组[1, 5, 13, 21]和[2, 4, 9,15],和最小的3个数对为(1, 2)、(1, 4) 和 (2, 5)。

分析:观察一下解这套题逻辑,先把数组1的第一个数和数组2的第一个数组成一对,这就是第一个最小的数对。那么第二个呢?要么是数组1的第一个数和数组2的第二个数,即(1, 4);要么是数组1的第二个数和数组2的第一个数(5, 2)。通过计算,是(1, 4)。那么比(1, 4)大一点的数呢?那就是(1, 9)和(5, 4)……所以不断根据上一个最小的数对,把比上一个数大一点的数加入到队列中,再进行比较,直到找出所有的k个最小的数对。

注意,用这种逻辑会出现的问题是,数对中会有重复。

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using PII = std::pair<int*, int*>;
struct greaterPtr
{
    bool operator() (PII p1,PII p2)
    {
        if (*p1.first + *p1.second <= *p2.first + *p2.second)
            return 0;
        else
            return 1;
    }
};
std::vector<PII> getKthPairOfNum(int *arr1, int m, int *arr2, int n, int k)
{
    std::vector<PII> result;
    if (m <= 0 || n <= 0 || k <= 0) return result;
    if (arr1 == nullptr || arr2 == nullptr) return result;
    int *p1 = arr1;
    int *p2 = arr2;
    std::priority_queue<PII,std::vector<PII>, greaterPtr> minHeap;
    minHeap.push(std::pair<int*, int*>(p1,p2));
    while (k != 0){
        auto curPtr = minHeap.top();
        p1 = curPtr.first;
        p2 = curPtr.second;
        minHeap.pop();
        minHeap.push(std::pair<int*,int*>(p1+1, p2));
        minHeap.push(std::pair<int*,int*>(p1, p2+1));        
        if (result.size() > 0){ 
            auto last = result.back(); 
            if (last.first == p1 && last.second == p2) 
                continue; 
        } 
    result.push_back(curPtr);
        k--;
    }
}
void test1()
{
    int arr1[] = {1, 5, 13, 21};
    int arr2[] = {2, 4, 9, 15};
    auto result = getKthPairOfNum(arr1, 4, arr2, 4, 3);
    int len = result.size();
    for (auto i : result){
        printf("(%d,%d)\n", *i.first, *i.second);
    }
}
int main()
{
    test1();
}

这份代码中涉及到一个priority_queue在构造最小堆中,使用自定义的比较策略。需要传入一个函数对象作为第三个参数,可以是结构、类、或者模板类、模板函数、仿函数。

相关文章
|
5月前
|
缓存 JavaScript 前端开发
《凭什么撼动Node.js?Bun和Zig性能优势深度揭秘》
Node.js长期主导服务器端运行时,但新兴的Bun和Zig正带来新挑战。Bun是一款高性能JavaScript运行时,基于Zig语言开发,启动速度快4倍于Node.js,依赖管理效率提升25倍。它集成了打包、转译、测试等功能,简化开发流程。Zig则以精细的内存管理和跨平台能力助力Bun性能飞跃,同时在服务端渲染、命令行工具开发等场景中表现出色。尽管Node.js生态成熟,Bun和Zig正逐步改写JavaScript运行时格局,推动技术进步。
193 15
|
存储 机器学习/深度学习 算法
【数据结构与算法篇】深入浅出——二叉树(详解)
【数据结构与算法篇】深入浅出——二叉树(详解)
813 0
|
消息中间件 缓存 NoSQL
高并发幂等计数器的设计与实现
高并发幂等计数器的设计与实现
326 0
高并发幂等计数器的设计与实现
|
Oracle 关系型数据库 MySQL
Flink CDC产品常见问题之flink Oraclecdc 捕获19C数据时报错错如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
6月前
|
SQL 关系型数据库 MySQL
MySQL:CTE 通用表达式
CTE(通用表表达式)为处理复杂查询提供了强大的工具。通过普通CTE,可以简化查询逻辑,提高可读性;通过递归CTE,可以优雅地处理层级结构数据。掌握CTE的使用,对于提升SQL查询能力和优化数据库操作有着重要意义。希望本文能帮助你更好地理解和使用MySQL中的CTE,提高工作效率和代码质量。
239 7
|
9月前
|
API 数据库
京东图片搜索商品拍立淘接口(JD.item_search_img)
拍立淘是阿里巴巴淘宝平台推出的基于图像识别技术的购物应用功能,旨在提升商品搜索效率与准确性。用户可通过上传图片快速找到相似商品。其核心接口item_search_img利用先进图像识别技术提取商品特征,并在数据库中匹配相似商品,返回包含商品ID、标题、价格等详细信息的结果列表,支持按价格、销量等多种方式排序,极大优化了用户的购物体验。
|
10月前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
479 1
|
机器学习/深度学习 人工智能 负载均衡
【AI大模型】分布式训练:深入探索与实践优化
在人工智能的浩瀚宇宙中,AI大模型以其惊人的性能和广泛的应用前景,正引领着技术创新的浪潮。然而,随着模型参数的指数级增长,传统的单机训练方式已难以满足需求。分布式训练作为应对这一挑战的关键技术,正逐渐成为AI研发中的标配。
531 5
|
消息中间件 负载均衡 Java
Spring Cloud 2023常见20道面试题
以下是20个2023年面试中可能会遇到的Spring Cloud常见问题以及参考答案:
1686 0
|
域名解析 弹性计算 资源调度
ECS域名问题之绑定如何解决
ECS(Elastic Compute Service,弹性计算服务)是云计算服务提供商提供的一种基础云服务,允许用户在云端获取和配置虚拟服务器。以下是ECS服务使用中的一些常见问题及其解答的合集: