808. 分汤
题目 你有两种汤,A 和 B,每种初始为 n 毫升。在每一轮中,会随机选择以下四种操作中的一种,每种操作的概率为 0.25,且与之前的所有轮次 无关: 1. 从汤 A 取 100 毫升,从汤 B 取 0 毫升 2. 从汤 A 取 75 毫升,从汤 B 取 25 毫升 3. 从汤 A 取 50 毫升,从汤 B 取 50 毫升 4. 从汤…
题目 你有两种汤,A 和 B,每种初始为 n 毫升。在每一轮中,会随机选择以下四种操作中的一种,每种操作的概率为 0.25,且与之前的所有轮次 无关: 1. 从汤 A 取 100 毫升,从汤 B 取 0 毫升 2. 从汤 A 取 75 毫升,从汤 B 取 25 毫升 3. 从汤 A 取 50 毫升,从汤 B 取 50 毫升 4. 从汤…
题目 给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。 如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。 示例 1: 输入:n = 1 输出:true 解释:20 = 1 示例 2: 输入:n = 16 输出:true 解释:24 = 16 示例 3: 输入:n = 3 输出:false 提示:…
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows = 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows = 1 输出: [[1]] 提示: * 1 <= numRows <= 30 解题代码 class Solution { public: vector&…
堆(Heap)本质上是一种特殊的树状数据结构,通常用完全二叉树来实现。它的主要特点是满足“堆属性”: * 大顶堆 (Max-Heap): 任何一个父节点的值都大于或等于它的所有子节点的值。这意味着,堆的根节点(顶部)存放的是整个堆中的最大值。 * 小顶堆 (Min-Heap): 任何一个父节点的值都小于或等于它的所有子节点的值。这意味着,堆的根节点(顶部)存放的是整个堆中的最小值。 C++中的实现 (std::priority_queue) std::priority_queue 默认实现的是一个大顶堆。 * int: 存储的元素类型。 * std::vector<int>: 实现堆所用的底层容器,vector是默认且最常用的选项。 * std::greater<int>: 比较函数。默认是std::less<int>(产生大顶堆)…
for (declaration : range_expression) { // 循环体 (loop body) // 在这里可以使用 declaration 来访问 range_expression 中的当前元素 } * declaration: 声明一个变量,用于在每次迭代中存储 range_expression 中的一个元素。 * 这个变量的类型通常可以由编译器通过 range_expression 中元素的类型自动推断(使用 auto),或者你可以显式指定类型。 * 你可以声明为值 (type var)、引用 (type& var) 或常量引用 (const type& var),具体取决于你是否需要修改元素以及是否希望避免不必要的拷贝。 * range_expression: 一个可以被迭代的对象,例如: * STL 容器(如 std::vector, std::string,…
1. 计算数据流的中位数 中位数是将一个数据集分成数量相等的上下两部分的值。我们的核心思想就是维护这两个“部分”。 核心思想:双堆 我们使用两个堆来模拟被中位数分开的数据集: 1. 一个大顶堆 (Max-Heap) small_half: 用于存储数据流中较小的那一半数字。堆顶是这一半数据中的最大值。 2. 一个小顶堆 (Min-Heap) large_half: 用于存储数据流中较大的那一半数字。堆顶是这一半数据中的最小值。 为了让这两个堆能够正确地“分割”数据流,我们必须始终维持两个不变的规则: 1. 大小平衡: 两个堆的大小要么相等,要么大顶堆 small_half 比小顶堆 large_half 多一个元素。这样可以确保中位数总是在两个堆的顶部产生。 2. 数值关系: 大顶堆 small_half 中的所有元素都必须小于或等于小顶堆 large_half 中的所有元素。 算法步骤 每当一个新的数据 num 到来时,…
* 左值 (lvalue, locator value): 可以放在赋值运算符=左边的表达式。它代表一个有身份 (identity) 的、持久的对象或内存位置。你可以对它取地址(使用 &)。 * 右值 (rvalue, read value): 只能放在赋值运算符=右边的表达式。它代表一个没有身份的、临时的值。你通常不能对它取地址。 更现代、更准确的理解是基于“身份”: * 左值:有一个持久的身份(identity),在表达式结束后依然存在。就像一个有门牌号的房子。 * 右值:是一个即将被销毁的临时值,没有持久的身份。就像你刚算出来的 2+3 的结果 5,这个 5 只是一个临时值。 左值 (lvalue) 左值是指定了内存中某个位置的表达式。 特征: 1. 有持久的内存地址。 2. 可以通过地址访问。 3.…
C++20 中最具变革性的特性之一:范围库 (Ranges Library),彻底改变了我们与标准模板库(STL)算法交互的方式,使代码更具表现力、更简洁、也更安全。 1. C++20 之前的问题:迭代器 在 C++20 之前,几乎所有的 STL 算法都依赖于一对迭代器 (begin, end) 来指定要操作的元素序列。这种设计虽然灵活,但存在诸多痛点: * 冗长和重复:每次调用算法,你都需要传递 container.begin() 和 container.end()。这非常啰嗦。 * 容易出错:很容易意外地传递不匹配的迭代器对(例如,一个来自 vector1 的 begin 和一个来自 vector2 的 end),这会导致未定义行为。…