【算法】经典算法题

文章目录

  • 专题一:双指针
    • 1. 移动零
    • 2. 复写零
    • 3. 快乐数
    • 4. 盛最多水的容器
    • 5. 有效三角形的个数
    • 6. 查找总价格为目标值的两个商品
    • 7. 三数之和
    • 8. 四数之和
  • 专题二:滑动窗口
    • 1. 长度最小的子数组
    • 2. 无重复字符的最长字串
    • 3. 最大连续1的个数 III
    • 4. 将 x 减到 0 的最小操作数

专题一:双指针


1. 移动零


在这里插入图片描述

题目解析
在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

// 写法一
class Solution 
{
public:void moveZeroes(vector<int>& nums) {// 1、下标初始化int dest = -1, cur = 0;// 2、数组划分while(cur < nums.size()){if(nums[cur]) swap(nums[++dest], nums[cur++]);else ++cur;}}
};// 写法二
class Solution 
{
public:void moveZeroes(vector<int>& nums) {for(int dest = -1, cur = 0; cur < nums.size(); ++cur)if(nums[cur]) // 处理 非0 元素swap(nums[++dest], nums[cur]);}
};/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

2. 复写零


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:void duplicateZeros(vector<int>& nums) {// 1、初始化int dest = -1, cur = 0, n = nums.size();// 2、找到最后一个复写的数while(true){if(nums[cur]) dest += 1;else dest += 2;if(dest >= n - 1) break;++cur;}cout << nums[cur] << endl;// 1.5、预处理 -> 让 dest 的下标有效if(dest == n){if(nums[cur]) --cur, --dest;else {nums[n - 1] = 0;dest -= 2;cur -= 1;}}// 2、双指针从后往前进行复写操作while(cur >= 0){if(nums[cur]) nums[dest--] = nums[cur--];else{nums[dest--] = 0;nums[dest--] = 0;cur--;} }}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

3. 快乐数


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
private:// 计算每个位置上的数字的平方和inline static int BitSum(int num){int ret = 0;while(num){int t = num % 10;ret += t * t;num /= 10;}return ret;}public:bool isHappy(int n) {int slow = n, fast = BitSum(n);while(slow != fast){slow = BitSum(slow);fast = BitSum(BitSum(fast));}return slow == 1;}
};

4. 盛最多水的容器


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:int maxArea(vector<int>& height) {int left = 0, right = height.size() - 1;int ret = INT_MIN;while(left != right){// 容积 = 长度 * 高度int v = (right - left) * min(height[left], height[right]);ret = max(ret, v);// 移动指针 - 谁小移动谁height[left] < height[right] ? ++left : --right;}return ret;}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

5. 有效三角形的个数


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:int triangleNumber(vector<int>& nums) {// 1、优化sort(nums.begin(), nums.end());// 2、利用双指针解决问题int ret = 0, n = nums.size();for(int i = n - 1; i >= 2; --i){int left = 0, right = i - 1;while(left < right){// 当 a+b>c ,a下标属于 [left, right-1]时,都能和 b、c 构成三角形// 当 a+b<=c ,b下标属于[left-1, right]时,都不能和 a、c 构成三角形if(nums[left] + nums[right] > nums[i]){ret += right - left;--right;}else ++left;}}// 返回值return ret;}
};/*
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
*/

6. 查找总价格为目标值的两个商品


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:vector<int> twoSum(vector<int>& price, int target) {// 1、数据初始化int left = 0, right = price.size() - 1;// 2、利用双指针解决问题while(left < right){int sum = price[left] + price[right];if(sum < target) ++left;else if(sum > target) --right;else return {price[left], price[right]};}// 题目没有明确说明没有结果的话会怎么样,那么该题的测试用例应该都是有结果的// 为了照顾编译器要求一定要返回一个结果,所以我们最后返回一个空数组即可return {};}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

7. 三数之和


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:vector<vector<int>> threeSum(vector<int>& nums) {// 1、初始化int n = nums.size();vector<vector<int>> ret;// 2、排序sort(nums.begin(), nums.end());// 3、依次固定一个数for(int i = 0; i < n - 2;){// 4、双指针算法找到两数之和等于 aim 的元素int left = i + 1, right = n - 1, aim = -nums[i];while(left < right){int sum = nums[left] + nums[right];if(sum < aim) ++left;else if(sum > aim) --right;else {ret.push_back( {nums[i], nums[left], nums[right]} );++left, --right; // 保证 left、right 选择的元素不漏// 对 left、right 已经选择过的元素去重while(left < right && nums[left] == nums[left - 1]) ++left;while(left < right && nums[right] == nums[right + 1]) --right;}}// 保证 i 选择的元素不漏++i; // 对 i 已经选择过的元素去重while(i < n - 2 && nums[i] == nums[i - 1]) ++i;}// 5、返回最终结果return ret;}
};
/*
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
*/

8. 四数之和


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {// 1、初始化int n = nums.size();vector< vector<int> > ret;// 2、排序sort(nums.begin(), nums.end());// 3、依次固定一个数,然后使用“三数之和”解决问题for(int i = 0; i < n - 3;) {// 4、再依次固定一个数,然后使用“双指针”解决问题for(int j = i + 1; j < n - 2;) {int left = j + 1, right = n - 1;double aim = (double)target - nums[i] - nums[j];// 5、双指针算法找到两数之和等于 aim 的元素while(left < right){double sum = nums[left] + nums[right];if(sum < aim) ++left;else if(sum > aim) --right;else{ret.push_back( {nums[i], nums[j], nums[left], nums[right]} );++left, --right; // 保证 left、right 选择的元素不漏// 对 left、right 已经选择过的元素去重while(left < right && nums[left] == nums[left - 1]) ++left;while(left < right && nums[right] == nums[right + 1]) --right;}}// 保证 j 选择的元素不漏++j;// 对 j 已经选择过的元素去重while(j < n - 2 && nums[j] == nums[j - 1]) ++j;}// 保证 i 选择的元素不漏++i;// 对 i 已经选择过的元素去重while(i < n - 3 && nums[i] == nums[i - 1]) ++i;}// 6、返回最终结果return ret;}
};
/*
- 时间复杂度:O(n^3)
- 空间复杂度:O(1)
*/

专题二:滑动窗口


1. 长度最小的子数组


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:int minSubArrayLen(int target, vector<int>& nums) {// 1、初始化int n = nums.size();int minLength = INT_MAX;// 2、使用滑动窗口解决问题for(int left = 0, right = 0, sum = nums[0]; right < n;){if(sum >= target) {minLength = min(minLength, right - left + 1);sum -= nums[left++];}else {if(++right < n)sum += nums[right];}}// 3、返回值return minLength == INT_MAX ? 0 : minLength;}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

2. 无重复字符的最长字串


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:int lengthOfLongestSubstring(string s) {// 1、初始化int n = s.size();vector<int> count(256);int left = 0, right = 0, ret = 0;// 2、滑动窗口int length = 0; //用来记录窗口长度while(right < n){if(!count[s[right]]) //进窗口{++count[s[right]];++length;++right;ret = max(ret, length); //更新结果}else //出窗口{--count[s[left]];--length;++left;}}// 3、返回值return ret;}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

3. 最大连续1的个数 III


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:int longestOnes(vector<int>& nums, int k) {// 1、初始化int n = nums.size();int ret = INT_MIN;// 2、滑动窗口int left = 0, right = 0;int length = 0; // 当前子数组中最长连续 1 的长度int zero = 0;  // 当前子数组中 0 出现的次数while(right < n){if(nums[right] != 0) // nums[right] 非 0,此时 right 一定入窗口{ret = max(ret, ++length);++right;}else{if(zero + 1 <= k) {ret = max(ret, ++length);++zero;++right;}else{if(nums[left++] == 0)  --zero;--length;}}}// 3、返回值return ret;}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

4. 将 x 减到 0 的最小操作数


在这里插入图片描述


题目解析
在这里插入图片描述


算法原理
在这里插入图片描述


代码编写

class Solution 
{
public:int minOperations(vector<int>& nums, int x) {// 1、初始化int sum = 0;for(const auto e : nums) sum += e;int target = sum - x;// 2、细节处理(数组中所有元素都大于0,所以 target 小于 0 是不存在的)if(target < 0) return -1;// 3、滑动窗口int ret = -1;for(int left = 0, right = 0, tmp = 0; right < nums.size();){// 进窗口tmp += nums[right++];// 出窗口while(tmp > target) tmp -= nums[left++];// 更新结果if(tmp == target) ret = max(ret, right - left);}// 4、返回结果return ret == -1 ? ret : nums.size() - ret;}
};
/*
- 时间复杂度:O(n)
- 空间复杂度:O(1)
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/212311.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC(三)

十、拦截器 1、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置&#xff1a; <bean class"com.atguigu.interceptor.FirstInterceptor">…

C#,OpenCv开发指南(02)——OpenCvSharp编程入门与矩阵Mat的基础知识

在 Visual Studio 中很方便搭建与使用 OpenCV 的 C# 的开发环境&#xff0c;几乎不用键盘输入。 使用 C# 开发 OpenCV 可以直接成为工业软件产品&#xff0c;而不是实验室程序。世界上几乎所有的视频厂家都提供 C# OpenCV 开发接口。 C#&#xff0c;人工智能&#xff0c;深度学…

【jvm】虚拟机之堆

目录 一、堆的核心概述二、堆的内存细分&#xff08;按分代收集理论设计&#xff09;2.1 java7及以前2.2 java8及以后 三、堆内存大小3.1 说明3.2 参数设置3.3 默认大小3.4 手动设置3.5 jps3.6 jstat3.7 OutOfMemory举例 四、年轻代与老年代4.1 说明 五、对象分配过程5.1 说明5…

2020年12月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 关于广播消息,以下说法正确的是? A:只有角色,可以通过“广播消息”积木,向其他角色或是背景发送消息 B:只有背景,可以通过“广播消息”积木,向其他角色或是背景发送消息 C:背…

初识Java 18-3 泛型

目录 边界 通配符 编译器的能力范畴 逆变性 无界通配符 捕获转换 本笔记参考自&#xff1a; 《On Java 中文版》 边界 在泛型中&#xff0c;边界的作用是&#xff1a;在参数类型上增加限制。这么做可以强制执行应用泛型的类型规则&#xff0c;但还有一个更重要的潜在效果…

计算机中了halo勒索病毒怎么清除,halo勒索病毒解密数据恢复

科技的进步加快了企业发展的步伐&#xff0c;网络技术的不断应用为企业的生产运营提供了极大帮助&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了halo勒索病毒攻击&#…

YOLOv5分割训练,从数据集标注到训练一条龙解决

最近进行了分割标注&#xff0c;感觉非常好玩&#xff0c;也遇到了很多坑&#xff0c;来跟大家分享一下&#xff0c;老样子有问题评论区留言&#xff0c;我会的就会回答你。 第一步&#xff1a;准备数据集 1、安装标注软件labelme如果要在计算机视觉领域深入的同学&#xff0…

若依vue-修改标题和图标

因为我们拉下来的代码,图标和logo是若依的,这和我们需要做出来的效果有差别 这个时候就需要去对应的文件内去修改标题和图标 (主要就是这两个地方的图标和标题) 修改菜单里面的logo以及文字 修改文字 位置: src/layout/component/Sidebar/Logo.vue 此处的title文字是定义在…

Python跳动的爱心

系列文章 序号文章目录直达链接1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心https://want595.blog.csdn.net/article/details/1295031234漂浮爱心https://want…

基于SSM的校园奶茶点单管理系统

基于SSM的校园奶茶点单管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 奶茶列表 登录界面 管理员界面 用户界面 摘要 随着社会的发展和科技的进…

ReentrantLock源码解析

ReentrantLock源码解析 文章目录 ReentrantLock源码解析一、ReentrantLock二、ReentrantLock 的 Sync、FairSync、NonfairSync2.1 Sync、FairSync、NonfairSync2.2 NonfairSync 下的 tryAcquire2.3 FairSync下的 tryAcquire2.4 tryRelease 三、lock.lock()3.1 NonfairSync.lock…

C语言——结构体(全)

目录 一、结构体的设计 二、结构体变量的初始化 2.1结构体在内存表示&#xff1b; 2.2结构体初始化&#xff1b; 2.3结构体指针变量 2.4结构体嵌套结构体 三、结构体成员访问 3.1、结构体成员访问 3.2、结构体变量和指针 ​3.3、结构体和函数 四、结构体与数组 五、…