Fantasy-JXF
  • Introduction
  • 机器学习
    • 机器学习基础
    • 机器学习实践
    • 机器学习算法
    • 集成学习
  • 深度学习
    • 深度学习基础
    • 深度学习实践
    • CNN
    • RNN
    • 优化算法
    • 序列建模
    • 《深度学习》整理
    • 术语表
  • 自然语言处理
    • NLP发展趋势
    • 自然语言处理基础
    • 句嵌入
    • 词向量
    • 多模态
    • 视觉问答(VQA)综述
    • 深度查询理解
      • 综述
  • 计算机视觉
    • 基本模型
  • 数学
    • 概率论
    • 微积分的本质
    • 深度学习的核心
  • 算法
    • 字符串
    • 数据结构
    • 数据结构Advanced
    • 双指针
    • 动态规划
    • 区间问题
    • 排列组合
    • 数学问题
    • 洗牌/采样/随机数
    • 大数运算
    • 海量数据处理
    • IO模板
    • 必备算法
    • LeetCode
    • 剑指Offer
    • 面试真题
  • 编程
    • C++基础
    • C++面向对象
    • C++左值与右值
    • Python基础
  • 笔试面经
    • 360
    • iHandy
    • 作业帮
    • 字节跳动
    • 小米
    • 度小满
    • 快手
    • 招行
    • 搜狐畅游
    • 滴滴
    • 爱奇艺
    • 百度
    • 百度2
    • 百度3
    • 百词斩
    • 腾讯
    • 迅雷
    • 顺丰
    • 旷视
    • 爱笔
    • 魔门塔
    • 搜狐
由 GitBook 提供支持
在本页
  • 二分查找
  • 离散版
  • 排序
  • 堆排序

这有帮助吗?

  1. 算法

必备算法

上一页IO模板下一页LeetCode

最后更新于6年前

这有帮助吗?

  • 一些必备算法,主要是 C++ 版本

    Index

二分查找

离散版

my_binary_search(vector<int>, int)

  • 没有重复元素时,目标值若存在,则返回索引;若不存在,返回 -1

  • 存在重复元素时,目标值若存在,则返回最小索引;若不存在,返回 -1

    int my_binary_search(vector<int>& nums, int v) {
        if (nums.size() < 1) return - 1;
    
        int lo = -1, hi = nums.size();  // hi = nums.size() - 1
    
        while (hi - lo > 1) {
            int mid = lo + (hi - lo) / 2;
            if (nums[mid] < v)
                lo = mid;
            else
                hi = mid;
        }
    
        return nums[lo + 1] == v ? lo + 1 : -1;
    }

my_lower_bound(vector<int>, int)

  • 返回大于、等于目标值的最小索引(第一个大于或等于目标值的索引)

    int my_lower_bound(vector<int>& nums, int v) {
        if (nums.size() < 1) return -1;
    
        int lo = -1, hi = nums.size();  // hi = nums.size() - 1
    
        while (hi - lo > 1) {                       // 退出循环时有:lo + 1 == hi
            int mid = lo + (hi - lo) / 2;
            if (nums[mid] < v)
                lo = mid;                           // 因为始终将 lo 端当做开区间,所以没有必要 `lo = mid + 1;`
            else
                hi = mid;                           // 而在 else 中,mid 可能就是最后的结果,所以不能 `hi = mid - 1`
        }
    
        return lo + 1; // 相比 binary_search,只有返回值不同
    }
  • 为什么返回 lo + 1?

    • 模板开始时将 (lo, hi) 看做是一个开区间,通过不断二分,最终这个区间中只会含有一个值,即 (lo, hi]

    • 返回 lo+1 的含义是,结果就在 lo 的下一个;

    • 在迭代的过程中,hi 会从开区间变为闭区间,而 lo 始终是开区间,返回 lo+1 显得更加统一。

    • 当然,这跟迭代的写法是相关的,你也可以使最终的结果区间是 [lo, hi),这取决于个人习惯。

my_upper_bound(vector<int>, int)

  • 返回大于目标值的最小索引(第一个大于目标值的索引)

    int my_upper_bound(vector<int>& nums, int v) {
        if (nums.size() < 1) return -1;
    
        int lo = -1, hi = nums.size();  // hi = nums.size() - 1
    
        while (hi - lo > 1) {
            int mid = lo + (hi - lo) / 2;
    
            if (nums[mid] <= v)                     // 相比 lower_bound,唯一不同点:`<` -> `<=`
                lo = mid;
            else
                hi = mid;
        }
    
        return lo + 1;
    }

排序

堆排序

建堆的时间复杂度

- 知乎

二分查找
离散版
my_binary_search(vector<int>, int)
my_lower_bound(vector<int>, int)
my_upper_bound(vector<int>, int)
排序
堆排序
建堆的时间复杂度
为什么建立一个二叉堆的时间为O(N)而不是O(Nlog(N))?