摘要:还在为算法头秃吗?还在面对LeetCode第一题不知所措吗?本文专为C++初学者打造,避开枯燥的数学推导,从STL神器入手,详解复杂度分析,并手把手带你搞定二分查找与双指针通用模板。无论是备战蓝桥杯、考研机试,还是校招面试,这篇文章都是你起飞的起点!建议收藏吃灰,随时拿出来复习。
目录
- 为什么选择C++刷算法?
- 磨刀不误砍柴工:时间复杂度(Big O)
- C++的物理外挂:STL标准库精选
- 算法初体验:拒绝死记硬背
- 核心思想一:二分查找(万能模板)
- 核心思想二:双指针(数组杀手)
- 新手进阶路线图(送给迷茫的你)
1. 为什么选择C++刷算法?
在算法竞赛(NOI/ICPC)和互联网大厂面试中,C++ 依然是王者。
- 速度快:tm同样的算法,Python可能会超时(TLE),但C++能过,你说这扯不扯。
- STL(标准模板库):这是C++最大的武器!队列、栈、堆、排序、二分,C++都帮你写好了,一行代码就能调用。
- 底层思维:学习C++能让你更懂内存管理和指针,这是面试官最喜欢的(也是我觉得c++最魅力的地方)。
2. 磨刀不误砍柴工:时间复杂度(Big O)
很多新手代码写出来了,但一提交就是“运行超时”。因为你没算复杂度!
简单来说,时间复杂度就是随着数据量 NNN 的增加,程序运行时间增长的趋势。
- O(1)O(1)O(1) 常数级:无论数据多少,跑一次就行。比如数组下标访问
arr[5]。 - O(N)O(N)O(N) 线性级:数据增加10倍,时间增加10倍。比如一个
for循环遍历数组。 - O(NlogN)O(N \log N)O(NlogN) 对数线性级:这是排序算法(
std::sort)的标准复杂度。 - O(N2)O(N^2)O(N2) 平方级:两层嵌套循环。数据量大时(比如 N=105N=10^5N=105),基本会超时。
💡 刷题经验:
一般题目限制时间是 1秒。
- 如果 N≤105N \le 10^5N≤105,你的算法通常需要是 O(N)O(N)O(N) 或 O(NlogN)O(N \log N)O(NlogN)。
- 如果 N≤2000N \le 2000N≤2000,你可以用 O(N2)O(N^2)O(N2)。
3. C++的物理外挂:STL标准库精选
别再手写快排了!熟练掌握STL,你的代码量能减少一半。
3.1 vector (变长数组)
它是C++中最常用的容器,可以动态扩容。
#include <vector>
#include <iostream>
using namespace std;
int main() {
//初始化一个包含1,2,3的数组
vector<int> nums={1,23};
// 尾部添加元素
nums.push_back(4);
// 遍历
for(int x:nums)
cout<<x<<" ";
// 输出: 1 2 3 4
cout<<"\n大小: "<<nums.size();//获取长度
return 0;
}
3.2 sort (排序神器)
默认从小到大排序,底层是快速排序+堆排序的混合优化,非常快。
#include <algorithm> // 必须包含头文件
#include <vector>
void example(){
vector<int> a={4,2,1,3};
// 排序区间 [begin, end)
sort(a.begin(),a.end());
// 此时 a 变为 {1, 2, 3, 4}
// 想要从大到小?加个参数
sort(a.begin(),a.end(),greater<int>());
}
4. 算法初体验:拒绝死记硬背
核心思想一:二分查找(Binary Search)
场景:在一个有序数组中查找某个数。
痛点:新手总是写不对 while(left < right) 还是 left <= right,死循环是常态。
万能闭区间模板(建议背诵):
//在 nums 中寻找 target,找到返回下标,没找到返回-1
int binarySearch(vector<int>& nums, int target){
int left=0;
int right=nums.size()-1;//注意这里是size-1
//只要区间不为空就继续找
while (left<=right) {
// 防止(left+right)溢出
int mid=left+(right-left)/2;
if (nums[mid]==target)
return mid;//找到了
else if(nums[mid]<target)
left=mid+1;//目标在右边,left 右移
else
right=mid-1;//目标在左边,right 左移
}
return -1;//没找到
}
核心思想二:双指针(Two Pointers)
场景:比如“移动零”、“两数之和(有序版)”。
思路:利用两个指针一前一后或一头一尾,将 O(N2)O(N^2)O(N2) 的暴力解法优化到 O(N)O(N)O(N)。
例题:给定一个有序数组,找到两个数之和等于 target。
vector<int> twoSum(vector<int>& numbers,int target){
int left=0;
int right=numbers.size()-1;
while(left<right){
int sum=numbers[left]+numbers[right];
if (sum==target){
return {left+1,right+1};//题目要求下标从1开始
else if(sum<target)
left++;//和太小了,让左指针变大
else
right--;//和太大了,让右指针变小
}
return {-1,-1};
}
5. 新手进阶路线图 🗺️
这也是很多大厂面试官推荐的刷题顺序:
- 入门阶段:
- 熟悉 C++ 语法(循环、函数、指针)。
- 掌握
vector,string,stack,queue,map的基本用法。 - 刷 LeetCode 简单题(Top 100 Liked)。
- 基础算法:
- 二分查找、双指针、滑动窗口。
- 递归与分治。
- 排序算法(手写快排、归并)。
- 数据结构进阶:
- 链表操作(反转链表是必考题)。
- 二叉树遍历(DFS/BFS)。
- 大BOSS阶段:
- 动态规划(DP)。
- 图论(Dijkstra, 最小生成树)。
总结
算法学习没有捷径,但有方法。不要一开始就去啃《算法导论》,多动手写代码,多画图理解流程才是王道。
如果你觉得这篇文章对你有帮助,请 点赞 + 收藏 + 关注 支持一下!后续我会更新《C++ STL 深度解析》和《动态规划套路详解》,敬请期待!
评论区打卡:你今天刷了几道题?
&spm=1001.2101.3001.5002&articleId=157698479&d=1&t=3&u=988cb34a105c40099d353b2a327de9b5)
1836

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



