- 温张鑫 的博客
七月day7
- @ 2025-7-21 17:04:04
T1 时间复杂度

T2 数据结构-vector动态数组
vector 是一种存储数据的容器
vector的创建:
vector<类型> 名字;
vector<int> v; // 创建一个int类型一维的空动态数组
vector<int> v(n,x); // 创建一个int类型一维动态数组,初始长度n,值为x。
vector<int> v[N]; // 创建一个int类型二维的动态数组,其中一维长度为N,二维长度可变
vector<vector<int>> v(n,vector<int>(m,x)) // 创建一个int类型n行m列的二维动态数组,初始值为x
vector的常用操作函数:
vector<int> v;
v.push_back(x); // 把元素x添加到末尾
v.pop_back(); // 把末尾元素删除
v.size(); // 返回长度
v[i]; // 获取下标为 i 的元素
v.front(); // 获取首位元素,也可以使用下标 v[0]
v.back(); // 获取末尾元素,也可以使用下标 v[v.size()-1]
v.clear(); // 清空容器
v.begin(); // 返回一个迭代器,指向容器的第一个元素
v.end(); // 返回一个迭代器,指向容器的最后一个元素的后一位
v.erase(v.begin()+1, v.begin()+4); // 删除容器中下标 1~4 的元素,删除的时间复杂度是O(n)
vector的循环遍历与输入输出:
(1) 往空数组添加元素
vector<int> v;
for (int i = 0; i < n; i++)
{
int x; cin >> x;
v.push_back(x); // 通过push_back往末尾添加n个数
}
(2) 提前声明数组大小,可以类似普通数组用下标输入
vector<int> v(n+1); // n+1是为了从1号下标开始存数据
for (int i = 1; i <= n; i++) cin >> v[i];
(3) 循环输出vector的元素
for (int i = 0; i < v.size(); i++) cout << v[i];
(4) 枚举型遍历
for (auto it : v) cout << it;
(5) 排序vector
sort(v.begin(), v.end())
(6) 对vector排序并去重
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end()); // unique函数必须先排序才能起到去重效果
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;//创建一个int类型二维的动态数组,其中一维长度为N,二维长度可变
vector<int> v[N];
int main()
{
int n,m;
cin>> n >> m;
while(m--)
{
int x,y;
cin>> x >> y;// 向第x个数组添加元素y
v[x].push_back(y);// 将元素y添加到第x个数组的末尾
}// 遍历每个数组,输出结果
for(int i = 1;i <= n;i++)
{
cout<< v[i].size() << " ";// 输出第i个数组的元素个数
sort(v[i].begin(),v[i].end());// 对第i个数组的元素进行排序
for(int j = 0;j < v[i].size();j++)
{ // 输出排序后的元素
cout<< v[i][j] << " ";
}
cout<< endl;// 换行继续处理下一个数组
}
return 0;
}
T3 #145. 数据结构-stack栈
栈(Stack)是一种基于 后进先出(LIFO) 原则的数据结构,它是一种线性表。栈具有两个主要操作:压入 (Push) 和弹出 (Pop)。
#include<stack>
stack<int> stk; // 创建int类型栈,名字为stk
stk.push(x) // 把x压栈
stk.pop() // 弹出栈顶元素
stk.top() // 查看栈顶元素
stk.size() // 返回栈内元素个数
stk.empty() // 返回栈是否为空
#include<bits/stdc++.h>
using namespace std;
stack<int> t;
int main(){
int m;
cin>> m;// 读取操作次数
while(m--){
string j;
cin>> j;
if(j == "push")
{
int x;
cin>> x;// 读取要压入栈的元素
t.push(x);// 将元素压入栈顶
}
else if(j == "pop")
{
t.pop();// 弹出栈顶元素
}
else if(j == "empty"){// 判断栈是否为空,判断后输出"YES"或"NO"
cout<<(t.empty()?"YES":"NO")<< endl;
} //三元运算符
else if(j == "query"){
cout<< t.top()<< endl;// 输出栈顶元素的值
}
}
return 0;
}
T4 数据结构-queue队列
队列(Queue)是一种常见的数据结构,它遵循先进先出(FIFO)的原则。队列有两个主要的操作:
入队:向队尾插入新元素。 出队:从队头移除元素。
除了这两个基本操作外,队列通常还包括以下操作:
队列判空:检查队列是否为空。
队列长度:获取队列中元素的个数。
获取队头元素:获取队头元素的值,但不移除它。
队列常用于模拟排队、任务调度等场景。在后续算法学习中,BFS广度优先搜索也要借助队列来实现。
STL 队列用法
#include<queue>
queue<int> q;
q.push(x); // 队尾插入x
q.pop(); // 弹出队头
q.front(); // 查看队头
q.back(); // 查看队尾
q.size(); // 查看q元素个数
q.empty(); // 查看q是否为空
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>> n >> m;// 输入总人数n和报数间隔m
queue<int> q;// 使用队列存储当前圈中的所有人
for(int i = 1;i <= n;i++) q.push(i);// 初始化队列,将编号为1到n的人依次入队
int cnt = 0;// 报数计数器,记录当前报数的值
while(q.size())// 当队列不为空时,继续模拟出圈过程
{
cnt++;// 报数递增
int c = q.front();// 取出队首元素(当前报数的人)
q.pop();// 队首元素出队
if(cnt % m == 0)// 判断当前报数是否为m的倍数,如果是,则当前人出圈(不重新入队)
{
cout<< c << " ";// 输出出圈人的编号
}
else// 如果不是,则当前人重新入队尾,继续参与报数
{
q.push(c);
}
}
return 0;
}
T5 数据结构-set和unordered_set集合
set 是按照特定顺序存储唯一元素的容器,即自带排序和去重。它非常适合处理需要同时兼顾查找、插入和删除的情况。元素放入 set 后不支持修改,但可以删除。
和数学中的集合相似,set 中不会出现值相同的元素,如果需要有相同元素,则可以使用 multiset,multiset 除了此特性之外,其他地方与 set 没啥区别,所以不再单独介绍。
创建一个set:
set<类型> 名字;
set的常用操作方法:
s.insert(x) 当容器中没有等价元素的时候,将元素 x 插入到 set 中。
s.erase(x) 删除值为 x 的所有元素,返回删除元素的个数。
s.clear() 清空 set。
s.count(x) 返回 set 内键为 x 的元素数量。
s.find(x) 在 set 内存在键为 x 的元素时会返回该元素的迭代器,否则返回 end()。
s.empty() 返回容器是否为空。
s.size() 返回容器内元素个数。
输出方法:
set<int> s;
s.insert(1);
s.insert(3);
s.insert(6);
for (auto it:s)
cout << it << " ";
for (auto it = s.begin(); it!=s.end(); it++)
cout << *it << " ";
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int N;// 输入整数的数量
cin >> N;
set<int> q;// 使用set存储整数,自动去重并排序
for (int i = 0; i < N; i++)
{ // 读取N个整数,并插入到set中
int num;
cin >> num;
q.insert(num); // set自动去重,重复元素只保留一个
}
}
cout << q.size() << endl; // 输出去重后的元素个数
for (auto it = q.begin(); it != q.end(); it++) // 遍历set中的元素
{
cout << *it;// 输出当前元素
if (next(it) != q.end())
{ // 在元素之间输出空格,但最后一个元素后不输出空格
cout << " ";
}
}
cout << endl;// 换行
return 0;
}
T6 数据结构-map和unordered_map哈希表
map 是有序键值对容器(自动按照键排序),它的元素的键是唯一的。搜索、移除和插入操作均拥有对数复杂度。可以把map理解成高级的桶数组,桶数组只能实现 int --> int 的映射,map则不受限制。
创建一个map:
map<类型, 类型> 名字;
比如要存储学生的名字和对应成绩,可以创建map<string, int> score;
map的常用操作方法:
map<int,int> mp;
mp[3] = 5; // 通过赋值创建一个键值对映射
mp[4] = 2;
mp[2] = 7;
mp.erase(4); // 删除{4,2}这个键值对
cout << mp.count(2); // 输出1,表示2这个键存在
cout << mp.count(5); // 输出0,表示5这个键不存在
// 枚举型遍历访问map的所有键值对
for (auto it : mp)
{
cout << it.first << " " << it.second << endl;
}
unordered_map 【哈希表】的基础用法和map一样,只不过它不会自动排序,所以访问速度更快。
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main()
{
int n;
cin>> n;// 输入整数的数量
map<ll,int> j;// 使用map统计每个整数出现的次数
for(int i = 0;i < n;i++)// 读取n个整数,并统计每个整数的出现次数
{
ll x;
cin>> x;
j[x]++;// 对应整数的计数器上加1
}
for (auto it : j)// 遍历map,按顺序输出每个整数和这个数的出现次数
{
cout << it.first << " " << it.second << endl;
}// it.first 是整数的值,it.second 是该整数出现的次数
return 0;