C++二分查找算法:有序矩阵中的第 k 个最小数组和(二)

简介: C++二分查找算法:有序矩阵中的第 k 个最小数组和

优化增加结果

vector<int> vRet;
  for (const auto& pr : pre)
  {
    for (const auto& cu : cur)
    {
      if (pr + cu < right)
      {
        vRet.emplace_back(pr + cu);
      }
      else
      {
        break;
      }
    }
  }
  while (vRet.size() < m_iK)
  {
    vRet.emplace_back(right);
  }

和小于right的数量<=k,如果不足够,则补right。时间复杂度由O(nk)降低到O(k+n)。

直接使用封装类

namespace NBinarySearch
{
  template<class INDEX_TYPE,class _Pr>
  INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE right, _Pr pr)
  {
    while (right - left > 1)
    {
      const auto mid = left + (right - left) / 2;
      if (pr(mid))
      {
        right = mid;
      }
      else
      {
        left = mid;
      }
    }
    return right;
  }
}
class Solution {
public:
  int kthSmallest(vector<vector<int>>& mat, int k) {
    m_c = mat.front().size();
    m_iK = k;
    vector<int> pre = mat[0];
    for (int r = 1; r < mat.size(); r++)
    {
      pre = GetLessKSum(pre, mat[r]);
    }
    return pre.back();
  }
  vector<int> GetLessKSum(const vector<int>& pre, const vector<int>& cur)
  {
    auto GetLessEqualSumNum = [&pre, &cur, this](const int iSum)-> bool
    {
      int iNum = 0;
      for (const auto& pr : pre)
      {
        iNum += std::upper_bound(cur.begin(), cur.end(), iSum - pr) - cur.begin();
      }
      return iNum >= m_iK;
    };
    const int right = NBinarySearch::FindFrist(0, 5000 * 40, GetLessEqualSumNum);   
    vector<int> vRet;
    for (const auto& pr : pre)
    {
      for (const auto& cu : cur)
      {
        if (pr + cu < right)
        {
          vRet.emplace_back(pr + cu);
        }
        else
        {
          break;
        }
      }
    }
    while (vRet.size() < m_iK)
    {
      vRet.emplace_back(right);
    }
    sort(vRet.begin(), vRet.end());
    if (vRet.size() > m_iK)
    {
      vRet.erase(vRet.begin() + m_iK, vRet.end());
    }
    return vRet;
  }
  int GetLessEqualSumNum(const vector<int>& pre, const vector<int>& cur,int iSum)
  {
    int iNum = 0;
    for (const auto& pr : pre)
    {
      iNum += std::upper_bound(cur.begin(), cur.end(), iSum - pr)- cur.begin();
    }
    return iNum;
  }
  int m_iK;
  int m_c;
};

2023年3月暴力版

直接保留前k个。时间复杂度:O(mknlogk)

class Solution {
public:
int kthSmallest(vector<vector>& mat, int k) {
m_r = mat.size();
m_c = mat[0].size();
std::priority_queue pre;
pre.push(0);
for (int r = 0; r < mat.size(); r++)
{
std::priority_queue dp;
while (pre.size())
{
int t = pre.top();
pre.pop();
for (int c = 0; c < m_c; c++)
{
dp.push(mat[r][c] + t);
if (dp.size() > k)
{
dp.pop();
}
}
}
pre.swap(dp);
}
return pre.top();
}
int m_r, m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。

https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程

https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨子曰:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境:

VS2022 C++17


本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

相关文章
|
3天前
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
21 4
|
24天前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
1月前
|
算法 C++
c++学习笔记04 数组
这篇文章是C++学习笔记4,主题是数组。
37 4
|
1月前
|
C++
拥抱C++面向对象编程,解锁软件开发新境界!从混乱到有序,你的代码也能成为高效能战士!
【8月更文挑战第22天】C++凭借其强大的面向对象编程(OOP)能力,在构建复杂软件系统时不可或缺。OOP通过封装数据和操作这些数据的方法于对象中,提升了代码的模块化、重用性和可扩展性。非OOP方式(过程化编程)下,数据与处理逻辑分离,导致维护困难。而OOP将学生信息及其操作整合到`Student`类中,增强代码的可读性和可维护性。通过示例对比,可以看出OOP使C++代码结构更清晰,特别是在大型项目中,能有效提高开发效率和软件质量。
23 1
|
1月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
30天前
|
C++
C++ PCL 计算多个RT矩阵变换后的变换矩阵
C++ PCL 计算多个RT矩阵变换后的变换矩阵
25 0
|
30天前
|
C++ 索引
C++数组、vector求最大值最小值及其下标
C++数组、vector求最大值最小值及其下标
53 0
|
1月前
|
算法 搜索推荐 C++
c++常见算法
C++中几种常见算法的示例代码,包括查找数组中的最大值、数组倒置以及冒泡排序算法。
17 0
|
1月前
|
安全 编译器 C语言
C++入门-数组
C++入门-数组
|
10天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
56 30