数组操作时间复杂度:
特点:
[]
或vector.at()
如何实现一个变长数组?
时间复杂度:
思考:若释放空间阀值设为50%,会怎么样
声明初始化一个vector
#include
vector vec; //声明一个int型向量
vector vec(5); //声明一个初始大小为5的int向量
vector vec(10, 1); //声明一个初始大小为10且值都是1的向量
vector vec(tmp); //声明并用tmp向量初始化vec向量
vector tmp(vec.begin(), vec.begin() + 3); //用向量vec的第0个到第2个值初始化tmp
int arr[5] = {1, 2, 3, 4, 5};
vector vec(arr, arr + 5); //将arr数组的元素用于初始化vec向量
//说明:当然不包括arr[4]元素,末尾指针都是指结束元素的下一个元素,
//这个主要是为了和vec.end()指针统一。
vector vec(&arr[1], &arr[4]); //将arr[1]~arr[4]范围内的元素作为vec的初始值
基本操作
(1). 容量
(2). 修改
(3)迭代器
(4)元素的访问
算法
// 遍历
vector::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << endl; // meanue1
for (size_t i = 0; i < vec.size(); i++) {
cout << vec.at(i) << endl; // meanuel2
}
// 元素翻转
#include
reverse(vec.begin(), vec.end());
// 元素排序
#include
sort(vec.begin(), vec.end()); //采用的是从小到大的排序
//如果想从大到小排序,可以采用上面反转函数,也可以采用下面方法:
bool Comp(const int& a, const int& b) {
return a > b;
}
sort(vec.begin(), vec.end(), Comp);
知识点简单,主要是多练习熟悉一下。
数组插入删除很贵O(n),引入链表
首先加入保护节点,哨兵节点
ListNode protect = new ListNode(0, head); // (value, ->next)
双向链表,双保护节
时间复杂度:
时间复杂度
只能访问、push、pop顶部的元素
操作
#include
#include
stack mystack1;
stack > mystack2;
时间复杂度
#include
#include
queue m;
queue > n;
操作
时间复杂度O(1)
一般队列以“时间”为顺序(先进先出)
优先队列按照元素的“优先级”取出
许多数据结构可以用来实现优先队列,例如二叉堆、二叉平衡树等
deque的API
1.1deque构造函数
deque deqT;//默认构造形式
deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
deque(n, elem);//构造函数将n个elem拷贝给本身。
deque(const deque &deq);//拷贝构造函数。
==1.2 deque赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
deque& operator=(const deque &deq); //重载等号操作符
swap(deq);// 将deq与本身的元素互换
1.3 deque大小操作
deque.size();//返回容器中元素的个数
deque.empty();//判断容器是否为空
deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
//遍历容器
void printDeque(const deque &d)
{
for(deque::const_iterator it = d.begin(); it != d.end(); it++)
{
cout<<*it<<" ";
}
cout<
2.1 deque双端插入和删除操作
push_back(elem);//在容器尾部添加一个数据
push_front(elem);//在容器头部插入一个数据
pop_back();//删除容器最后一个数据
pop_front();//删除容器第一个数据
2.2 deque数据存取
at(idx);//返回索引idx所指的数据,如果idx越界,抛出out_of_range。
operator[];//返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。
front();//返回第一个数据。
back();//返回最后一个数据
2.3 deque插入操作
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
2.4 deque删除操作
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
时间复杂度
访问最值:O(1)
插入:一般是O(logN)
去最值:O(logN)
定义:priority_queue
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆
// 升序队列
priority_queue ,greater > q;
// 降序队列
priority_queue ,less >q;
// greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
//对于基础类型 默认是大顶堆
priority_queue a;
//等同于 priority_queue, less > a;
和队列基本操作相同:
数组
88.合并有序数组 easy
https://leetcode-cn.com/problems/merge-sorted-array/
两个数组从后往前的指针开始比较,谁大放谁,放入后并----相应的指针
防止被覆盖,从后开始放最大的
边界问题
//一个数什么时候要的模板(重复)
int n = 0;
for (int i = 0; i < nums.size(); i++){
if (i == 0 || nusm[i] != nums[i - 1]){
nums[n] = nums[i];
n++;
}
}
26.去重 easy
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
283.移动零 easy
https://leetcode-cn.com/problems/move-zeroes/
链表
临值查找 hard
https://www.acwing.com/problem/content/description/138/
141.环形链表 easy
https://leetcode-cn.com/problems/linked-list-cycle/
142.环形链表II mid
https://leetcode-cn.com/problems/linked-list-cycle-ii/
206.反转链表 easy
https://leetcode-cn.com/problems/reverse-linked-list/
注意最后的指向null的指针
next指针改为指向last的,但是链表操作中没有last指针,开一个新的指针记录last
最后返回的是指针
//遍历链表:
while (head != nullptr){
head = head->next // 如果需要更改,新建一个指针暂存
}
25.K个一组翻转链表 hard
https://leetcode-cn.com/problems/reverse-nodes-in-k-group/
分组,找到每一组的开始、结尾。按组遍历
// 找到一组k的结尾
private ListNode getEnd(ListNode head, intk){
while (head != null){
k--;
if (k == 0)break;
return head;
}
}
反转一组
// 反转两个节点之间的链表
private void reverseList(ListNode head, ListNode end){
if (head == end) return;
ListNode last = head;
head = head->next
// 改变每条边,访问链表
while (head != end){
ListNode nextHead = last;
// 改变一条边
head->next = last;
// last, head的地址向后移动一位
last = head;
head = nextHead;
}
end->next = last;
}
上一组跟本组的head(旧的end)建立联系
让本组的新结尾(end)跟下一组建立联系
边界问题
栈
20.有效的括号 easy
https://leetcode-cn.com/problems/valid-parentheses/
155.最小栈 medium
https://leetcode-cn.com/problems/min-stack/
150.逆波兰式 后缀表达式求值 medium
https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/
227 medium &224 hard 基本计算器 中缀表达式
https://leetcode-cn.com/problems/basic-calculator-ii/
https://leetcode-cn.com/problems/basic-calculator/
// 字符串转数值模板
long long val = 0;
for (char ch : s){
if (ch >='0' && ch <= '9'){
val = val * 10 + ch - '0';
}
}
定义优先级
转后缀,再求解
homework
21.合并两个有序链表 easy
https://leetcode-cn.com/problems/merge-two-sorted-lists/
66.加一 easy
https://leetcode-cn.com/problems/plus-one/
641.设置循环双端队列 medium
https://leetcode-cn.com/problems/design-circular-deque/