LeetCode C++ 笔记

1. 二分查找避免死循环

在二分查找中,通常会有两个主要操作:

  1. 更新左边界 (left = mid 或 left = mid + 1)。
  2. 更新右边界 (right = mid - 1 或 right = mid)。

二分查找通过不断缩小 [left, right] 的区间,最终使得 left == right 或者区间变得不可再缩小,从而退出循环。

假设我们使用经典的二分查找方法来计算 mid

mid = (left + right) >> 1;

如果在某些情况下,更新区间时没有正确地缩小区间,就会导致死循环。例如:

  • 假设 left = 2right = 3
  • 计算 mid = (2 + 3) >> 1 = 2
  • 如果条件导致 left = mid,那么 left 的值仍然是 2,而 right 的值仍然是 3
  • 在下一次迭代中,mid 的值仍然是 2,区间没有缩小,导致死循环。

为了避免这种情况,通常需要在某些场景下通过 +1 或其他方法来确保区间能够正确缩小。

在这段代码中,mid = (left + right + 1) >> 1 的作用是使 mid 向上取整(更偏向右边界):

  • 当 left + right 是奇数时,+1 的效果是使得 mid 更靠近右边界。
  • 这可以确保当更新区间时,left 或 right 都会发生变化,从而避免死循环。

A. C++ STL 容器

STL 中的容器有序列容器和关联容器,容器适配器 (congtainer adapters: stack,queue, priority queue),位集(bit set),串包(string package)等等。

  1. 序列式容器(Sequence containers),每个元素都有固定位置——取决于插入时机和地点,和元素值无关,vector、deque、list。
    • Vector:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时。
    • Deque:是 double-ended queue 的缩写,可以随机存取元素(用索引直接存取),数织头部和尾部添加或移除元素都非常快速,但是在中部或头部安插元素比较费时。
    • List:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针。
  2. 关联式容器(Associated containers,元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap等。
    • Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Mulisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找。
    • Map/Multimap:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找。

容器类自动申请和释放内存,无需new和delete操作。

A.1. std::string(严格意义非容器但类似)

容量管理

  • size_t size() const noexcept:返回字符串长度。
  • size_t length() const noexcept:返回字符串长度(等价于 size())。
  • size_t max_size() const noexcept:返回字符串的最大大小。
  • void resize(size_t n):调整字符串大小。
  • void resize(size_t n, char c):调整大小并填充字符 c
  • size_t capacity() const noexcept:返回当前分配的容量。
  • void reserve(size_t new_cap = 0):调整容量大小。
  • void shrink_to_fit():释放多余的容量。
  • bool empty() const noexcept:检查字符串是否为空。

访问操作

  • char& front():返回第一个字符(可修改)。
  • const char& front() const:返回第一个字符(只读)。
  • char& back():返回最后一个字符(可修改)。
  • const char& back() const:返回最后一个字符(只读)。
  • const char* c_str() const noexcept:返回 C 字符串格式的内容。
  • const char* data() const noexcept:返回数据指针(不可修改)。
  • char* data() noexcept:返回数据指针(可修改,从 C++17 开始)。
  • std::string substr(size_t pos = 0, size_t n = npos) const:提取子字符串。

修改操作

  • void clear() noexcept:清空字符串。
  • std::string& insert(size_t pos, const std::string& str):插入字符串。
  • std::string& insert(size_t pos, const char* s):插入 C 字符串。
  • std::string& insert(size_t pos, size_t n, char c):插入 n 个字符 c
  • std::string& erase(size_t pos = 0, size_t n = npos):删除子字符串。
  • std::string& replace(size_t pos, size_t len, const std::string& str):替换子字符串。
  • void push_back(char c):在字符串末尾添加字符。
  • void pop_back():移除字符串末尾的字符。
  • void swap(std::string& str) noexcept:交换两个字符串内容。

查找操作

  • size_t find(const std::string& str, size_t pos = 0) const noexcept:查找子字符串。
  • size_t find(const char* s, size_t pos = 0) const:查找 C 字符串。
  • size_t find(char c, size_t pos = 0) const noexcept:查找字符。
  • size_t rfind(const std::string& str, size_t pos = npos) const noexcept:从右查找子字符串。
  • size_t find_first_of(const std::string& str, size_t pos = 0) const noexcept:查找第一个匹配的字符。
  • size_t find_last_of(const std::string& str, size_t pos = npos) const noexcept:查找最后一个匹配的字符。
  • size_t find_first_not_of(const std::string& str, size_t pos = 0) const noexcept:查找第一个不匹配的字符。
  • size_t find_last_not_of(const std::string& str, size_t pos = npos) const noexcept:查找最后一个不匹配的字符。

比较操作

  • int compare(const std::string& str) const noexcept:比较两个字符串。
  • int compare(size_t pos, size_t len, const std::string& str) const:比较子字符串。

运算符重载

  • std::string& operator=(const std::string& str):拷贝赋值运算符。
  • std::string& operator=(std::string&& str) noexcept:移动赋值运算符。
  • std::string& operator=(const char* s):从 C 字符串赋值。
  • std::string& operator=(char c):赋值单个字符。
  • std::string& operator=(std::initializer_list<char> ilist):从初始化列表赋值。
  • char& operator[](size_t pos):获取指定位置的字符(可修改)。
  • const char& operator[](size_t pos) const:获取指定位置的字符(只读)。
  • char& at(size_t pos):获取指定位置的字符(带边界检查,可修改)。
  • const char& at(size_t pos) const:获取指定位置的字符(带边界检查,只读)。
  • std::string& operator+=(const std::string& str):拼接字符串。
  • std::string& operator+=(const char* s):拼接 C 字符串。
  • std::string& operator+=(char c):拼接单个字符。
  • bool operator==(const std::string& lhs, const std::string& rhs):比较相等。
  • bool operator!=(const std::string& lhs, const std::string& rhs):比较不相等。
  • bool operator<(const std::string& lhs, const std::string& rhs):小于比较。
  • bool operator>(const std::string& lhs, const std::string& rhs):大于比较。
  • bool operator<=(const std::string& lhs, const std::string& rhs):小于等于比较。
  • bool operator>=(const std::string& lhs, const std::string& rhs):大于等于比较。
  • std::string operator+(const std::string& lhs, const std::string& rhs):拼接两个字符串。
  • std::string operator+(const std::string& lhs, const char* rhs):拼接字符串和 C 字符串。
  • std::string operator+(const char* lhs, const std::string& rhs):拼接 C 字符串和字符串。
  • std::string operator+(const std::string& lhs, char rhs):拼接字符串和单个字符。
  • std::ostream& operator<<(std::ostream& os, const std::string& str):输出流支持。
  • std::istream& operator>>(std::istream& is, std::string& str):输入流支持。

构造函数

  • std::string():默认构造函数,创建一个空字符串。
  • std::string(const std::string& str):拷贝构造函数。
  • std::string(std::string&& str) noexcept:移动构造函数。
  • std::string(const char* s):从 C 字符串构造。
  • std::string(const char* s, size_t n):从 C 字符数组的前 n 个字符构造。
  • std::string(size_t n, char c):构造一个包含 n 个字符 c 的字符串。
  • std::string(std::initializer_list<char> ilist):从初始化列表构造。

A.2. std::vector

A.3. std::unordered_map

B. C++ STL 迭代器

C. C++ STL 算法

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇CUDA 学习笔记