计算机算法知识及题目解析
前言
我创作这篇博客的目的是记录学习技术过程中的笔记。希望通过分享自己的学习经历,能够帮助到那些对相关领域感兴趣或者正在学习的人们。
目录
- 计算机算法知识及题目解析
-
- 前言
- 目录
-
-
- 1.时间复杂度、空间复杂度 最坏情况
- 2.O(log n) 忽略底数的描述
- 3.OJ(online judge) 超时时间是1s
- 4.递归的时间复杂度与空间复杂度
- 5.数列求和公式
- 6.C++内存管理
- 7.二分法
- 8. a + b 2 \frac{ {a+b}}{2} 2a+b ---> a + b − a 2 a + \frac{ {b-a}}{2} a+2b−a 原因:防止溢出
- 9.万能库
- 10.STL
- 11.自定义排序(后面深入模版再查看原因)
- 12.this指针
- 13.const修饰
- 14.algorithm
- 15.数组
- 16.列表初始化和构造函数传参
- 17.常识
- 18.双指针法(快慢指针法)
- 19.关于链表的数学
- 20.哈希法:***数组、set、map***。
- 21.KMP算法——快速查找匹配串
- 22.**栈与递归之间在某种程度上是可以转换的!**(但是有的场景难度可能比较大,例如:**都知道回溯法其实就是递归,但是很少人用迭代的方式去实现回溯算法!)**
- 23.单调队列
- 24.二叉树
-
- 24.1二叉树的种类
- 24.2二叉树的存储方式
- 24.3二叉树的遍历方式
- 24.4 前序遍历、中序遍历、后序遍历、层序遍历中,处理节点方式可变以适应具体题目。
- 24.5 满二叉树的节点个数= 2 树深度 − 1 2^{\text{树深度}} - 1 2树深度−1
- 24.6 从根节点到该节点的最长简单路径边的条数或者节点数——前序遍历 void getDepth(TreeNode* node, int depth) ;从该节点到叶子节点的最长简单路径边的条数或者节点数——后序遍历 int getHeight(TreeNode* node)//返回值可用负数作为标记;
- 24.7 假设树中没有重复的元素,前序遍历和中序遍历可以唯一确定一颗二叉树;后序遍历和中序遍历可以唯一确定一颗二叉树;前序遍历和后序遍历不可以唯一确定一颗二叉树。
- 24.8 二叉搜索树
- 24.9 二叉树问题的一些细节
- 25.图论
- 26.递归三要素
- 27.回溯算法
- 28.贪心算法
- 29.动态规划
- 30.单调栈
- 31.前缀和与差分
- 32.记忆化递归
- 33.排序
- 34.位运算
- 35.二进制枚举子集
- 36.线段树
- 37.**双栈解决「通用表达式」问题的通用解法**
- 38.OJ在线编程常见输入输出练习
-
1.时间复杂度、空间复杂度 最坏情况
2.O(log n) 忽略底数的描述
3.OJ(online judge) 超时时间是1s
O ( n ) O(n) O(n) $ 10^8 $ ------> O ( n 2 ) O(n^2) O(n2) 1 0 4 10^4 104
求解: x 2 = 1 0 8 x^2=10^8 x2=108
x = 1 0 4 x=10^4 x=104
O ( n ) O(n) O(n) $ 10^8 $ ------> O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)) 1 0 7 10^7 107
求解: 1 0 x ∗ x = 1 0 8 10^x*x=10^8 10x∗x=108
x ≈ 7 x≈7 x≈7
4.递归的时间复杂度与空间复杂度
递归的时间复杂度=递归次数*每次递归中的操作次数
递归的空间复杂度=递归深度*每次递归中的空间复杂度
1)设n为具体数字
2)画树形图
5.数列求和公式
等差数列 $\ S_n = n \cdot a_1 + \frac{n \cdot (n - 1)}{2} \cdot d $
等比数列 S n = a 1 ⋅ ( 1 − q n ) 1 − q S_n = \frac{ {a_1 \cdot (1 - q^n)}}{ {1 - q}} Sn=1−qa1⋅(1−qn)
6.C++内存管理

7.二分法
前提条件:1)有序 2)无重复元素
区间定义:[left,right]
1)while(left<=right)
2)right=middle-1;left=middle+1;
3)middle=left+(right-left)/2;
8. a + b 2 \frac{ {a+b}}{2} 2a+b —> a + b − a 2 a + \frac{ {b-a}}{2} a+2b−a 原因:防止溢出
9.万能库
#include<bits/stdc++.h>
using namespace std;
int main(){
return 0;
}
10.STL
vector 动态数组
初始化:
vector<int> a;
vector<int> a(10);//值不定
vector<int> a(10,1);//值为1
vector<int> a(b.begin(),b.begin()+3);//值为b中第1个到第3个元素
int b[]={1,2,4,5,9,8};
vector<int> a(b,b+6);
vector<int> a={1,2,4,5,9,8};//容器 列表初始化
方法:
a.front();a.back();a[i];
a.clear();
a.erase(a.begin(),a.begin()+3);a.erase(a.begin()+1);//删除第2个元素 //时间复杂度为O(n)
a.pop_back();a.push_back(5);//时间复杂度为O(1)
a.insert(a.begin()+1,5);a.insert(a.begin(),3,5);a.insert(a.begin()+1,b+3,b+6);a.insert(a.begin()+1,b.begin()+3,b.begin()+6);//时间复杂度为O(n)
a.size();
a.resize(10);a.resize(10,2);
a==b;a>=b;a<=b;a!=b;a<b;a>b;
deque 双端数组 与vector相比
a.pop_front();//时间复杂度为O(1)
a.push_front();//时间复杂度为O(1)
list 双向链表 与vector相比
a.pop_front();//时间复杂度为O(1)
a.push_front();//时间复杂度为O(1)
string 字符串 与vector相比
初始化:
string str;
string str(10,'A');
string str="ABC";
方法:
str.resize(10);str.resize(10,'C');
str.push_back('A');str.append("ABC");str+='A';str+="ABC";//时间复杂度为O(1)
str.insert(2,3,'A');str.insert(2,"ABC");str.insert(str.begin()+2,'A');str.insert(str.begin()+2,3,'A');str.insert(str.begin()+1,str2.begin()+3,str2.begin()+6);
str.erase(2);str.erase(2,1);// 删除从位置 2 开始的 1 个字符
str.erase(str.begin()+2);str.erase(str.begin(),str.begin()+3);
str.find('A');str.find("ABC");//返回子串的首字符位置,或若找不到这种子串则为 std::string::npos
str.substr(2);//提取从位置 2 开始,到字符串末尾的子字符串
str.substr(2,3);//提取从位置 2 开始,长度为 3 的子字符串
a==b;a>=b;a<=b;a!=b;a<b;a>b;//会先按照字典序比较字符串的字符,只有在字符相等的情况下才会考虑字符串的长度
queue 队列 容器适配器
a.push(x);
a.pop();
a.front();
a.back();
stack 栈 容器适配器
a.push(x);
a.pop();
a.top();
set 集合 升序
初始化:
set<int> a;//默认升序
set<int,less<int>> a;//升序
set<int,greater<int>> a;//降序
方法:
a.insert(x);
a.erase(a.begin(),a.begin()+3);a.erase(x);a.erase(a.begin()+1);//删除第二个元素
a.find(x);
a.begin();
a.end();
map 哈希
初始化:
map<int,string> list1;//默认升序
map<int,string,less<int>> list1;//升序
map<int,string,greater<int>> list1;//降序
map<int,string> list2 = {
{1,"java教程"},{2,"c++教程"},{3,"python教程"}};
map<int,string> list3 = {pair<int,string> (1,"java教程"),pair<int,string> (2,"c++教程")};
方法:
list1.insert(pair<int,int> (1,15));list1.insert({1,15});
a.erase(a.begin(),a.begin()+3);a.erase(1);a.erase(a.begin()+1);//删除第二个元素
a[1]=6;//如果键 1 不存在,map 容器会自动插入一个新的键值对
a.find(1);
a.begin();
a.end();
priority_queue 优先队列 大顶堆
初始化:
priority_queue<int> a;//默认大顶堆
priority_queue<int,vector<int>,less<int>> a;//大顶堆
priority_queue<int,vector<int>,greater<int>> a;//小顶堆
方法:
a.push(x);//O(log(n))
a.pop();//O(log(n))
a.top();
扩展:
1.统计最大前k个元素:k个元素的小顶堆(只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素)
multimap 哈希
方法:
a.count(key);
list1.insert(pair<int,int> (1,15));list1.insert({1,15});
a.erase(a.begin(),a.begin()+3);a.erase(x);//删除键为x的所有元素
a.erase(a.begin()+1);//删除第二个元素
//和map容器相比,multimap未提供at()成员方法,也没有重载[ ] 运算符
a.find(1);//若存在多个具有相同键的元素,只返回第一个匹配的元素
a.begin();
a.end();
a.equal_range(x);//查找键为 x 的元素范围,返回一个迭代器的pair对象,first成员等价于lower_bound(key)//返回一个迭代器,指向键>=k的第一个元素,second成员等价于upper_bound(key)//返回一个迭代器,指向键>k的第一个元素//lower_bound与upper_bound在有序容器如set、map、multiset、multimap使用
auto range = a.equal_range(1);
// 遍历范围内的元素
for (auto it = range.first; it != range.second; ++it) {
cout << it->first << ": " << it->second << endl;
}
multiset 集合 升序
方法:
a.count(x);
a.insert(x);
a.erase(a.begin(),a.begin()+3);a.erase(x);a.erase(a.begin()+1);//删除第二个元素
a.find(x);
a.begin();
a.end();
a.equal_range(x);
pair
pair<string,int> p={"hello",1};
pair<string,int> p("hello",1);
pair<string,int> p = make_pair("hello",1);
p.first; //第一个元素 =hello
p.second; //第二个元素 = 1
//套娃操作 用pair存储3个数据
pair<int, pair<int, int>> p(1,{2,3});
当pair 结合 sort()函数使用的时候, pair 默认对first升序,当first相同时对second升序(从小到大)。 也可以通过修改cmp函数达到对second排序
迭代器
迭代器实质上是一个指针,但是,并不是所有的容器的迭代器可以支持加减操作。
能进行算术运算的迭代器只有随机访问迭代器,要求容器元素存储在连续内存空间内;
即vector、string、deque的迭代器是有加减法的;
而map、set、multimap、multiset、list的迭代器是没有加减法的。他们仅支持++itr、–itr这些操作。
advance函数:将迭代器移动指定的距离
可以用于多种容器,包括 std::vector, std::list, std::deque 等。对于支持随机访问的容器(如 std::vector),std::advance 可以直接通过加法操作来移动迭代器。对于不支持随机访问的容器(如 std::list),std::advance 会通过多次递增或递减操作来达到目标位置。
vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
// 向前移动迭代器 2 位
advance(it, 2);
// 向后移动迭代器 1 位
advance(it, -1);
11.自定义排序(后面深入模版再查看原因)
const成员函数:const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
set:
//创建castle类
class Castle
{
public:
Castle(string name, int area) //提供有参构造函数
{
this->m_Name = name;
this->m_Area = area;
}
string m_Name; //建筑名称
int m_Area; //建筑面积
};
struct Castle
{
Castle(string name, int area) :m_Name(name), m_Area(area) {}
string m_Name; //建筑名称
int m_Area; //建筑面积
};
//创建降序仿函数(类)
class MyCustom
{
public:
//重载小括号()
bool operator()(const Castle& c1, const Castle& c2) const //注意后面加个const,否则报错
{
if (c1.m_Name != c2.m_Name)
return c1.m_Name > c2.m_Name;
else
return c1.m_Area > c2.m_Area; //按建筑面积降序排序
}
};
//在C++中,结构体是特殊的类。
//和类的唯一区别:具有不同的默认访问控制属性。类中默认private,结构体默认public。
//C++为为C语言中的结构体引入了成员函数、访问控制权限、继承、多态等面向对象特性。
struct MyCustom
{
//重载小括号()
bool operator()(const Castle& c1, const Castle& c2) const //注意后面加个const,否则报错 原因:set容器STL内部调用实参为const Date*
{
if (c1.m_Name != c2.m_Name)
return c1.m_Name > c2.m_Name;
else
return c1.m_Area > c2.m_Area; //按建筑面积降序排序
}
};
//利用列表初始化,创建对象
Castle c1 = { "餐厅", 235 };
//利用有参构造函数,创建对象
Castle c2("客厅", 666);
//创建set容器,注意尖括号里面的内容,说明创建的是Castle类对象,同时按指定的方法排序
set<Castle, MyCustom> ss;
sort():
//创建castle类
class Castle
{
public:
Castle(string name, int area) //提供有参构造函数
{
this->m_Name = name;
this->m_Area = area;
}
string m_Name; //建筑名称
int m_Area; //建筑面积
};
struct Castle
{
Castle(string name, int area) :m_Name(name), m_Area(area) {}
string m_Name; //建筑名称
int m_Area; //建筑面积
};
//创建降序仿函数(类)
class MyCustom
{
public:
//重载小括号()
bool operator()(const Castle& c1, const Castle& c2) const //注意后面加个const,否则报错
{
if (c1.m_Name != c2.m_Name)
return c1.m_Name > c2.m_Name;
else
return c1.m_Area > c2.m_Area; //按建筑面积降序排序
}
};
//在C++中,结构体是特殊的类。
//和类的唯一区别:具有不同的默认访问控制属性。类中默认private,结构体默认public。
//C++为为C语言中的结构体引入了成员函数、访问控制权限、继承、多态等面向对象特性。
struct MyCustom
{
//重载小括号()
bool operator()(const Castle& c1, const Castle& c2) const //注意后面加个const,否则报错 原因:set容器STL内部调用实参为const Date*, 而
{
if (c1.m_Name != c2.m_Name)
return c1.m_Name > c2.m_Name;
else
return c1.m_Area > c2.m_Area; //按建筑面积降序排序
}
};
static bool cmp(const Castle& c1, const Castle& c2) {
if (c1.m_Name != c2.m_Name)
return c1.m_Name > c2.m_Name;
else
return c1.m_Area > c2.m_Area; //按建筑面积降序排序
}
vector<Castle> ss;
//sort函数的第三个参数可以是函数对象(重载函数调用操作符(operator())来实现可调用操作的类的对象)
MyCustom mycustom;
sort(ss.begin(), ss.end(), mycustom);
//sort函数的第三个参数可以是函数指针(函数名也是函数地址)
sort(ss.begin(), ss.end(), cmp);
12.this指针
class Date
{
public:
//Print编译器处理前
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//Print编译器处理后
void Print(Data* const this) //注意const修饰,指针不能修改,指向的内容可以修改
{
cout << this->_year << "-" << this->_month << "-" << this > _day << endl;
}
//Init编译器处理前
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
//Init编译器处理后
void Init(Date* const this, int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
private:
int _year; // 年
int _month; // 月
int _day; // 日
};
int main()
{
Date d1;
Date d2;
Date d3;
d1.Init(2022, 10, 17);
d2.Init(2023, 10, 18);
//编译器实参改变
d1.Init(&d1, 2022, 10, 17);
d2.Init(&d2, 2023, 10, 18);
d1.Print();
d2.Print();
//编译器实参改变
d1.Print(&d1);
d2.Print(&d2);
return 0;
}
13.const修饰
1)const修饰变量:
const char *p = "hello"; // 非const指针,
// const数据
// 可以指向别的变量,但不可以通过修改所指向的变量的值
char * const p = "hello"; // const指针,
// 非const数据
// 可以修改所指向变量的值,但不可以指向别的变量
const char * const p = "hello"; // const指针,
// const数据
// 不可以修改所指向变量的值,也不可以指向别的变量
技巧:
const往右看,忽视数据类型,p代表指针内容不可改变,*p代表指针所指向的内容不可改变
2)const修饰函数:
const char* func();//函数声明
char* str = func();// error
const char* str = func(); //right
权限问题:——涉及指针或引用时,而普通变量之间主要是赋值关系。
权限不能放大(松),只能缩小(紧)或不变。
class Date
{
public:
//构造函数
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Printf()
{
cout << _year << "年" << _mon th << "月" << _day << "日" << endl;
}
private:
int _year;
int _month;
int _day;
};
void Func(const Date& d)
{
d.Printf();
}
int main()
{
Date d1(2023, 11, 1);
d1.Printf();
Date d2(2023, 11, 2);
Func(d2);//error
return 0;
}

14.algorithm
sort函数 默认升序
1)数组
int arr[]={3,1,4,1,5,9,2,6,5,3,5};
int n=sizeof(arr)/sizeof(int);
sort(arr,arr+n);
2)vector容器
vector<int> arr={3,1,4,1,5,9,2,6,5,3,5};
sort(arr.begin(),arr.end());
reverse函数 仅适用于容器,不适用于数组
vector<int> arr={3,1,4,1,5,9,2,6,5,3,5};
reverse(arr.begin(),arr.end());
"整体反转+局部反转"法
swap函数
1)数组
int arr[]={3,1,4,1,5,9,2,6,5,3,5};
swap(arr[i],arr[j]);
2)vector容器
vector<int> arr={3,1,4,1,5,9,2,6,5,3,5};
swap(arr[i],arr[j]);
3)变量
swap(a,b);
find函数
1)数组
int arr[]={1,3,5,7,9};
int n=sizeof(arr)/sizeof(int);
int* p=find(arr,arr+n,5);
p!=arr+n
2)vector容器
vector<int> vec={1,3,5,7,9};
auto iter=find(vec.begin(),vec.end(),5);
iter!=vec.end();
cmath
fabs(double x);//绝对值
floor(double x);//向下取整
ceil(double x);//向上取整
log(double x);//以e为底的对数
sin(double x);cos(double x);tan(double x);//参数为弧度
asin(double x);acos(double x);atan(double x);//返回的结果是以弧度为单位的角度值
round(double x);//四舍五入仅保留到整数位,保留小数位可先乘再除
__gcd(a,b);//最大公因数
a*b/__gcd(a,b);//最小公倍数
常量
const double PI=atan(1.0)*4;//精确的PI值
const int INF=(1<<30)-1;//避免大数+大数溢出
字符串与char* 字符指针、数字的相互转化
1)字符串转化字符指针
str.c_str();
2)字符指针转化数字
atoi(char_p);
atol(char_p);
atof(char_p);
3)字符串转化数字
stoi(str);
stol(str);
stoll(str);
stof(str);
stod(str);
stoll(str, nullptr, 2);//将二进制字符串转换为长长整型
4)数字转化字符串
to_string(num);
5)字符指针转化字符串
char* charPtr = "Hello, World!";
string str(charPtr);
string str;
str = charPtr;
全排列
1)vector
do{
}
while(next_permutation(nums.begin(),nums.end()));
2)数组
do{
}
while(next_permutation(arr,arr+n));
3)字符串
do{
}
while(next_permutation(str.begin(),str.end()));
printf函数
1)%md 变量超过m位则保持原样输出
2)输出string类型
string s = "Hello World";
printf("%s", s.c_str());
3)格式
%[标志][最小宽度][.精度][类型长度]类型。
d o(不输出前缀0) u x/X(不输出前缀0x) f/lf e/E c s p
- 左对齐 +输出符号 space 为正空格为负负号 0 前面为0
scanf函数
1)除了%c,scanf函数对%d,%s等其他格式把空白符和换行符视为结束
2)多行字符串输入
2
Apple is red.
Banana is yellow.
方法一:
scanf("%d",&a);//cin>>a;
getchar();
getline(cin,s1);//以换行符结束
getline(cin,s2);
方法二:
scanf("%d\n",&a);
getline(cin,s1);
getline(cin,s2);
3)读取到文件结尾(Window系统Dos平台Ctrl+Z代表文件结束符)
while(scanf("%d",&n)!=EOF){
...
}
sizeof函数
sizeof(arr);//数组大小
sizeof(str);//字符串对象大小 通常包含多个成员变量即不是简单的个数乘以类型字节数
sizeof(vec);//vector对象大小 通常包含多个成员变量即不是简单的个数乘以类型字节数
数据结构定义
链表
struct ListNode{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL){}
};
二叉树
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
lower_bound与upper_bound函数——时间复杂度 O ( l o g ( n ) ) O(log(n)) O(log(n)),内部实现基于二分查找
lower_bound//用于在有序容器查找第一个大于或等于给定值的元素位置。如果没有找到,它将返回指向容器末尾的迭代器(或指针)。左闭右开区间 不要求不重复
upper_bound//用于在有序容器查找第一个大于给定值的元素位置。如果没有找到,它将返回指向容器末尾的迭代器(或指针)。左闭右开区间不要求不重复
1)数组
int arr[] = {10, 20, 30, 40, 50};
int size = sizeof(arr)/sizeof(int);
auto lowerIt = lower_bound(arr, arr + size, 30);
if (lowerIt != arr + size) {
cout << "找到元素:" << *lowerIt << endl;
} else {
cout << "未找到元素" << endl;
}
2)vector容器
vector<int> vec = {10, 20, 30, 40, 50};
auto lowerIt = lower_bound(vec.begin(), vec.end(), 30);
if (lowerIt != vec.end()) {
cout << "找到元素:" << *lowerIt << endl;
} else {
cout << "未找到元素" << endl;
}
15.数组
1)数组传参:
一维数组:
void test(int arr[]);
void test(int arr[10]);
二维数组:
void test(int arr[][5]);
void test(int arr[3][5]);
2)赋值
局部变量一维数组、二维数组={0},其他元素默认赋值为0。
3)字符串
string s[11];//字符串数组可以像二维数组那样访问
16.列表初始化和构造函数传参
1)容器可初始化列表
string hex_16[16]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
2)new
Rectangle* p_rect=new Rectangle{5.0,6.0};//列表初始化
Rectangle* p_rect=new Rectangle(5.0,6.0);//有参构造函数
Rectangle* p_rect=new Rectangle;//无参构造函数
delete p_rect;
17.常识
1)1不是质数也不是合数。
2)1和任何数互质,其他情况下最大公因数为1就互质。
3)闰年要么可被4整除,但不可被100整除;要么可被400整除。
4)真因子:除了它本身以外的因子,包括1在内。
5)完全平方数:一个能表示成某个整数的平方的形式的数。
6)VS快速弹出智能提示:Ctrl+J。
7)32位系统下基本数据类型规模
类型 规模 输出格式符
int/long 10^9 %d
long long 10^18 %lld
unsigned long long 10^20 %llu
float %f
double %lf
8)蓝桥杯最大栈空间为256MB,即最大可以开10^7左右的数组空间。
9)set与vetor的相互转化
vector转set:
vector<int> nums1;
unordered_set<int> nums_set(nums1.begin(), nums1.end());
set转vector:
unordered_set<int> nums2;
vector<int> nums_vector(nums2.begin(), nums2.end());
10)验算:
输入规模的最小项、最大项;
输入规模的奇偶项;
输入值的负数、输入值的零;
输入值的无规律排列;
根据输入规模最大值决定是否开拓新空间;
11)排序算法时间复杂度
冒泡排序: O ( n 2 ) O(n^2) O(n2)
快速排序: O ( n ∗ l o g ( n ) ) O(n*log(n)) O(n∗log(n))
12)进阶时间复杂度计算
看每一个元素被操作的次数,每个元素在滑动窗口进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 $2 × n 也就是 也就是 也就是O(n)$
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0; // 滑动窗口数值之和
int i = 0; // 滑动窗口起始位置
int subLength = 0; // 滑动窗口的长度
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
13)二维动态数组的定义与赋值
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
res[i][j];
14)数组与链表的特性对比

15)单链表统一所有节点的删除操作和增加操作——设置一个虚拟头结点
head = dummyNode->next;

16)C++11基于范围的for循环——可以遍历支持迭代器的集合,如std::vector、std::list等,也可以遍历支持下标操作的集合,如std::arra
算法精讲与实践

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



