set操作

C++ set 容器基于红黑树实现,其核心操作的时间复杂度如下:

‌查找、插入、删除操作‌:平均和最坏情况均为 ‌O(log n)‌,其中 n 是集合中的元素数量。这种对数级性能得益于红黑树的自平衡特性。

‌遍历操作‌:时间复杂度为 ‌O(n)‌,需要访问每个元素

‌需要注意的点:‌

  1. ‌容器类型限制‌:array.begin() + 1这种写法要求容器支持随机访问迭代器,比如vectordeque或数组。如果是listset这类不支持随机访问的容器,这种写法会编译错误

函数功能示例
next(it) 获取下一个迭代器 next(numSet.begin())
prev(it) 获取上一个迭代器 prev(numSet.end())

主要删除方法:‌

🛠️ ‌删除指定值的元素‌

set<int> myset{1,2,3,4,5}; int num = myset.erase(2); // 删除值为2的元素

返回值num表示成功删除的元素个数(0或1)6。

🎯 ‌删除迭代器指向的元素‌

set<int>::iterator iter = myset.erase(myset.begin()); // 删除第一个元素

删除后,迭代器iter指向被删除元素的下一个位置6。

📋 ‌删除迭代器范围内的元素‌

set<int>::iterator iter2 = myset.erase(myset.begin(), --myset.end());

删除从开始到倒数第二个元素之间的所有元素6。

🧹 ‌清空整个集合‌

myset.clear(); // 删除所有元素

 

 

练习题目:220. 存在重复元素 III - 力扣(LeetCode)

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
        int n = nums.size();
        if (indexDiff == n) indexDiff = n - 1;
        set<int> array;
        map<int, int> vis;
        for (int i = 0; i <= indexDiff; i++) {
            if (!vis[nums[i]]) {
                vis[nums[i]] = 1;
                array.insert(nums[i]);
            } else {
                vis[nums[i]]++;
            }
        }

        int INF = 0x7fffffff;
        int min_v = INF;
        auto pre_it = array.begin();
        if (vis[*pre_it] > 1) min_v = 0;
        for (auto it = std::next(array.begin()); it != array.end(); it++) {
            // cout << *it << endl;
            min_v = min(min_v, abs(*pre_it - *it));
            if (vis[*it] > 1) min_v = min(min_v, 0);
            pre_it = it;
        }
        if (min_v <= valueDiff) return true;
        int k = indexDiff + 1;
        for (int i = k; i < n; i++) {
            // 处理旧元素
            if (vis[nums[i - k]] <= 1) {
                array.erase(nums[i - k]);
            }
            vis[nums[i - k]]--;
            // 插入新元素
            if (!vis[nums[i]]) {
                vis[nums[i]] = 1;
                array.insert(nums[i]);
                auto it = array.find(nums[i]);
                auto next_it = std::next(it);
                if (it != array.begin()) {
                    auto pre_it = std::prev(it);
                    min_v = min(min_v, abs(*pre_it - *it));
                }
                if (next_it != array.end()) {
                    cout << *next_it << endl;
                    min_v = min(min_v, abs(*next_it - *it));
                }
            } else {
                min_v = min(min_v, 0);
                vis[nums[i]]++;
            }

        }
        return min_v <= valueDiff;

    }
};

 

 

一、multiset简介

multiset 是C++标准库中的关联容器,基于红黑树实现,支持自动排序和重复元素存储。其核心特性包括:

  • ‌自动排序‌:元素插入时自动按升序排列(可通过自定义比较器改变顺序)。
  • ‌允许重复‌:与set不同,multiset允许存储相同值的多个副本。
  • ‌高效操作‌:插入、删除、查找的平均时间复杂度为O(log n)。
  • ‌迭代器支持‌:提供双向迭代器(不支持随机访问)。

二、关键接口

1. 基本操作

#include <set> // 头文件 std::multiset<int> ms; // 创建空multiset ms.insert(3); // 插入元素(允许重复) ms.erase(3); // 删除所有值为3的元素

 

2. 查找与统计

 
auto it = ms.find(3); // 查找值为3的元素(返回迭代器) int count = ms.count(3); // 统计值为3的元素个数

 

3. 遍历

 
for (auto it = ms.begin(); it != ms.end(); ++it) { std::cout << *it << " "; // 输出元素 }

 

三、与set的区别

特性setmultiset
元素唯一性 ✓(不允许重复) ✗(允许重复)
count()返回值 0或1 任意整数(重复元素个数)
适用场景 唯一值管理(如黑名单) 计分系统(允许同分)

四、自定义排序

通过仿函数(重载operator())实现自定义排序规则:

 
struct Descending { bool operator()(int a, int b) const { return a > b; } }; std::multiset<int, Descending> ms; // 降序排序

 

 

 

 
posted @ 2025-11-30 19:44  WTSRUVF  阅读(7)  评论(0)    收藏  举报