【代码随想录】刷题笔记Day10

目录

前言

C++容器的使用

vector常见用法

set常见用法

map常见用法

349. 两个数组的交集

350. 两个数组的交集 II

后言

前言

今天天气转暖了,一下子就燥热起来了,天气一变心也容易浮,赶紧刷几道代码题冷静一下

C++容器的使用

开始之前来学习一下C++的容器,熟悉熟悉这些高效的用法,今天先学vector、set和map吧,感觉最近就是这仨不太熟,以下知识点来自《算法笔记(胡凡)》,持续更新

vector常见用法

vector为向量,可理解为变长数组,还可以以邻接表的方式存储图

// vector的定义
vector name;  // 一维变长数组,可以int、double、char、node等
vector vi(100);  // 创建一个一维整数向量,默认初始化为0
vector vi(100, 0);  // 同上,加初始化0
vector> name;  // 二维变长数组,>>之间要加空格
vector vi[100];  // 二维变长数组,第一维定长100不能变

// vector的访问
// 下标访问
vi[index] = 1;  // 一维,从0到vi.size()-1
// 迭代器访问
vector::iterator it;  // 可以通过*it来访问vector里的元素
vector vi;
for(int i = 1; i <= 5; i++)(  // 循环完毕后v1中元素为12345
    vi.push_back(i);  // push_back(i)在vi的末尾添加元素i,即依次添加12345
}
vector::iterator it = vi.begin();  // vi.begin()为取vi的首元素地址,而it指向这个地址
auto it = vi.begin();  // 可以直接用auto自动推理类型,更简洁
for(int i = 0; i < 5; i++){
    printf("%d", *(it + i));  // 输出vi[i],vi[i]和*(vi.begin()+i)是等价的
}
for(vector::iterator it = vi.begin(); it != vi.end(); it++){  // 迭代器不支持it

set常见用法

set为集合,是一个内部自动有序且不含重复元素的容器。set是唯一的,如果要处理不唯一的情况用multiset,而unordered_set用了散列表,则更快了

// set的定义,类似vector
set name;

// set容器内元素的访问
set::iterator it;  // 只能通过迭代器,操作类似vector,不支持*(it+i)

// set常用函数
insert(x)  // 可将x插入set容器中,并自动递增排序和去重,O(logN)
find(value)  // 返回set中对应值为value的迭代器,O(logN)
erase(it)  // it为需要删除元素的迭代器,O(l)
erase(value)  // value为所需要删除元素的值,O(logN)
erase(first,last)  // 删除区间[first,last)内的所有元素,O(last-first)
size()  // 获得set内元素的个数,O(1)
clear()  // 清空set中的所有元素,O(N)
count(value)  // 是否有value,有则返回1,无则返回0

vector a;
set b(a.begin(), a.end());  //迭代器构造,如果有重复的,自动去重排序

map常见用法

map为映射,可以将任何基本类型映射到任何基本类型(包括STL容器),同样的,有multimap和unordered_map。

// map的定义
map mp;  // 前为键、后为值
map mp;  // 字符串映射不能用char数组
map,string> mp;  // set容器映射到字符串

// map元素访问
// 下标访问
map mp;
mp['c'] = 20;  // 键是唯一的
// 迭代器访问
it->first  // 当前映射的键,map会以键从小到大的顺序自动排序(红黑树)
it->second  // 当前映射的值

// map常用函数
find(key)  // 返回键为key的映射的迭代器,O(logN)
erase(it)  // it为需要删除的元素的迭代器,O(1)
erase(key)  // key欲删除的映射的键,O(logN)
erase(first,last)  // 删除区间[first,last)内的所有元素,O(last-first)
size()  // 获得map中映射的对数,O(1)
clear()  // 清空map中的所有元素,复杂度为O(N)
count(key)  // 是否有键,有则返回1,无则返回0
insert(pair(key, value));   // 将键值对插入map中

349. 两个数组的交集

  • 如果题目数少且特别分散,则要学会使用哈希数据结构:unordered_set,可自动去重
  • class Solution {
    public:
        vector intersect(vector& nums1, vector& nums2) {
            unordered_set result_set; // 存放结果,之所以用set是为了给结果集去重
            unordered_set nums_set(nums1.begin(), nums1.end());  //迭代器构造nums_set,如果有重复的,自动删除
            for (int num : nums2) {
                // 发现nums2的元素 在nums_set里又出现过
                if (nums_set.find(num) != nums_set.end()) {  // 如果找不到迭代器是end
                    result_set.insert(num);  // 将num插入,不会排序
                }
            }
            return vector(result_set.begin(), result_set.end());  // 转换为数组
            // return vector a(result_set.begin(), result_set.end());  // 如果是要用数组a的话
        }
    };
  • 由于力扣修改最大数为1000,所以也可以用数组去做(实际更高效)
  • class Solution {
    public:
        vector intersection(vector& nums1, vector& nums2) {
            unordered_set res;
            vector hash(1005, 0);  // int hash[1005] = {0}; 
            for(int x : nums1){
                hash[x] = 1;
            }
            for(int x : nums2){
                if(hash[x] == 1) res.insert(x);
            }
            return vector (res.begin(), res.end());
        }
    };

350. 两个数组的交集 II

  • 想用multiset的,但是发现好像不行,看官方题解还是得用unordered_map
  • class Solution {
    public:
        vector intersect(vector& nums1, vector& nums2) {
            if(nums1.size() > nums2.size()){  // 为了节省空间,存小的
                return intersect(nums2, nums1);
            }
            unordered_map hash;  // 哈希表存每个数字的个数
            for(int num : nums1){
                hash[num]++;
            }
            vector res;
            for(int num : nums2){
                if(hash.count(num)){  // 如果有交叉
                    res.push_back(num);  // 加入结果
                    hash[num]--;  // 用掉了一个
                }
                if(hash[num] == 0){  // 如果用完了
                    hash.erase(num);  // 及时删键
                }
            }
            return res;
        }
    };

后言

喜大普奔!刷题的时候接到了电话,网易伏羲产品岗的一面过了!明天二面!!exciting!

你可能感兴趣的:(代码随想录刷题笔记,数据结构,leetcode,算法,职场和发展)