优选算法[1]

目录

1.双指针;

2.滑动窗口;

3.二分查找;

4.前缀和;


1.双指针;

包括对撞指针和快慢指针(一般用来循环);

题目类型:移动零,复写零,快乐数,盛水最多的容器,有效三角形的个数,三数之和,四数之和。

举个例子:

移动零:

首先考虑暴力方法:直接遇到0元素插入到数组结尾。

优选之后:使用两个指针 (记录下标,并非真正的指针);cur和dest。

cur如果遇到0元素就++,非零元素就和dest进行交换,交换之后dest++;直到cur走到结尾。

代码编写:

class Solution 
{
public:void moveZeroes(vector<int>& nums) {int cur=0,dest=-1;while(cur<nums.size()){if(nums[cur]==0){cur++;}else{dest++;swap(nums[dest],nums[cur]);cur++;}}}
};

复写零:

如果指针此c前面开始复写会造成数据被覆盖的问题,那么采用从后面到前面的方法。

首先进行移动指针,cur遇到非零移动一步,dest移动一步,cur遇到零移动一步,dest移动两步。

还有特殊情况dest跳出边界了;就把 arr[dest-1]=0;dest-=2;cur-=1;

看cur的值是否为0,非零就将cur的值直接赋值给dest,是零就赋值两次给dest。直到cur遍历完。

代码编写:

class Solution 
{
public:void duplicateZeros(vector<int>& arr) {int dest=-1;int cur=0;int n=arr.size();//将指针移动尾部while(cur<n){if(arr[cur]){dest++;}else{dest+=2;}if(dest >= n-1) break;cur++;}//处理边界,可能跳出范围了if(dest == n){arr[dest-1]=0;dest-=2;cur--;}while(cur >= 0){if(arr[cur]){arr[dest--]=arr[cur--];    }else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
};

三数之和:

采用双指针的方法,首先固定一个数,只要找到和这个数相反的数之和就可以找到其他两个数。

那么就在 [i+1,n-1]之间进行查找。如果其和大于 t 那么就要将右边指针移动后一步;如果其和小于 t 那么就要将左边指针移动前一步。找到也不能停止,看是否有其他选择。

那么这里就会涉及到两个去重的操作。首先是left和right区间的去重,和上一次一样的数就直接跳过即可。外面固定的数也是一样的去重操作。

上代码:

class Solution 
{
public:vector<vector<int>> threeSum(vector<int>& nums) {int n=nums.size();vector<vector<int>> ret;//先进行排序sort(nums.begin(),nums.end());for(int i=0;i<n;){int left=i+1;int right=n-1;int target=-nums[i];while(left < right){int sum=nums[left]+nums[right];if(sum < target){left++;}else if(sum > target){right--;}else{//如果找到那么就插入ret,并且往后面看看,找到不同的解,如果有重复元素就跳过。ret.push_back({nums[i],nums[left],nums[right]});right--;left++;//跳过步骤while(left < right && nums[left]==nums[left-1]) left++;while(left <right &&nums[right]==nums[right+1])right--;}}i++;//i也是看重复元素.这个很考验能力,到底写哪里很重要。while(i < n && nums[i]==nums[i-1]) i++;}return ret;}
};

2.滑动窗口;

题目类型:长度最小的子数组,无重复字符的最长子串,最大连续1的个数,将x减少到零的最小操作数,。题目就是找进入窗口,出窗口,更新数据。

长度最小的子数组:

left和right,sum+=right的值,并且与 t 比较,len记录长度,大于t的话出窗口,更新len=right-left+1;并且left++。

上代码:

class Solution 
{
public:int minSubArrayLen(int target, vector<int>& nums) {//滑动窗口的题目就是1.进入窗口,2.出窗口,3.更新结果;//多看过程;int left=0,right=0;int len=INT_MAX;int sum=0;//while循环进不去;for循环简单。for(int left=0,right=0;right<nums.size();right++){//不进窗口就right++并且sum+;sum+=nums[right];//进窗口就判断小于,不断修改len以及sum.直到出去窗口;//相当于两层循环。while(sum >= target){len=min(len,right-left+1);sum-=nums[left++];}}return len==INT_MAX?0:len;}
};

  

3.二分查找;

定义left和right的指针。

分为朴素二分和复杂二分。

左右指针以及中间指针进行移动,来查找数据。

注意分析left,right,mid的取值。结束条件。

二分查找:

class Solution 
{
public:int search(vector<int>& nums, int target) {int left =0,right=nums.size()-1;while(left <= right){int mid=left+(right-left)/2;if(nums[mid] < target){left=mid+1;}else if(nums[mid] > target){right=mid-1;}else{return mid;}}return -1;}
};

 复杂二分:

class Solution 
{
public:vector<int> searchRange(vector<int>& nums, int target){if(nums.size()==0) return {-1,-1};//找左端点;int begin=0;int left=0,right=nums.size()-1;while(left < right)//自己画图分析是否等于{int mid=left+(right-left)/2;//自己分析;if(nums[mid] < target){left=mid+1;}else {right=mid;}}//判断是否有结果if(nums[left] != target){return {-1,-1};}else{begin=left;}//找右端点left=0,right=nums.size()-1;while(left < right){int mid=left+(right-left+1)/2;//自己分析;if(nums[mid] <= target){left=mid;}else{right=mid-1;}}return {begin,right};}
};

4.前缀和;

1.首先找规律,创建dp前缀和数组使用前缀和数组,完成要求。

#include <iostream>
using namespace std;
#include<vector>int main() 
{// 1.读入数据int n,q;cin>>n>>q;vector<int> arr(n+1);for(int i=1;i<=n;i++) cin>>arr[i];//预处理出来前缀和数组;vector<long long> dp(n+1);for(int i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i];//使用前缀和数组;int l = 0,r=0;while(q--){cin>>l>>r;cout<<dp[r]-dp[l-1]<<endl;}return 0;
}

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

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

相关文章

【每日力扣】235. 二叉搜索树的最近公共祖先与39. 组合总和问题描述

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义…

Python中类方法和静态方法的区别你知道吗?

​1.类方法 通过 classmethod 装饰器修饰的方法就是类方法 类方法可以通过类名或对象名调用&#xff0c;但是一般情况下使用类名调用&#xff08;节省内存&#xff09; 类方法中没有self.在类方法中不可以使用其它对象的属性和方法 类方法中一般会有一个参数cls&#xff0c;…

Crc冗余校验码设计

串行电路的位置&#xff0c;有异或门的地方是1&#xff08;生成多项式&#xff09; 简单的来说&#xff0c;如果最高位Q4 为0 的话&#xff0c;那么直接和 0 进行异或的话&#xff0c;实现的也是自己本身&#xff0c;直接左移就可以了 如果最高是1的话&#xff0c;那么就要和生…

【数据结构与算法】:选择排序与快速排序

&#x1f525;个人主页&#xff1a; Quitecoder &#x1f525;专栏&#xff1a;数据结构与算法 我的博客即将同步至腾讯云开发者社区&#xff0c;邀请大家一同入驻&#xff1a;腾讯云 欢迎来到排序的第二个部分&#xff1a;选择排序与快速排序&#xff01; 目录 1.选择排序1.…

如何export windows中的环境变量

在大语言模型&#xff08;LLM&#xff09;学习过程中&#xff0c; 利用 jupyter 导入环境变量时出现以下问题&#xff0c; C:\Users\zhangxuantao>export SENSENOVA_SKxxxxxx export 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 原因是学习教程中用…

VTK安装(C++)并配置vs

准备工作&#xff1a; 1.VTK下载包(此教程使用VTK8.2.0) 2.CMAKE(此教程使用3.29.0) 在此不过多赘述&#xff0c;可在网上搜索cmake安装 3.visual studio(此教程使用vs2019) VTK下载及编译&#xff1a; 1、找到自己适合的VTK版本,我选择的是VTK8.2.0。 1.1 官网下载&#xff…

天水麻辣烫榜上有名!2024适合普通人的创业项目!2024最适合创业的三大行业!2024热门创业项目!

1、天水麻辣烫 最近济南6天开了4家甘肃麻辣烫天天爆满 有店日营业额破万元有店主飞甘肃天水学习5天回来迅速开店&#xff01;选择天水麻辣烫作为创业项目绝对是一个明智的选择。趁着现在的热度&#xff0c;开设一家门店&#xff0c;借助其已经积累的名气和口碑&#xff0c;创业…

Docker常用命令的使用及镜像的构建

1.docker的好处 在开发中可能会遇到一个问题&#xff0c;一个程序在自己电脑上能跑&#xff0c;但是换到服务器上就不行了。如果我们重新搭建环境&#xff0c;需要重新部署mysql,es,redis等组件很麻烦。有了docker之后&#xff0c;我们可以快速完成项目的部署。同时docker的隔…

L1-072 刮刮彩票 分数 20 (巧用一维数组,数组加和)

啊啊啊啊啊啊啊啊明明就想出来了&#xff0c;明明就&#xff0c;就差这2分为什么为什么啊&#xff01;&#xff01;&#xff01;忘记当 tt 大于3小于6时应该 - 3 了&#xff0c;哎呦喂&#xff0c;三位的数组哪有4&#xff0c;5&#xff0c;6啊啊啊啊啊忘记减了&#xff0c;忘了…

C语言数据结构(7)——树、二叉树前言

欢迎来到博主的专栏——C语言数据结构 博主ID&#xff1a;代码小豪 文章目录 树二叉树特殊二叉树满二叉树完全二叉树 完全二叉树的存储结构 树 树是一个非线性的数据结构&#xff0c;由N个结点构成的集合。 树的各个结点由一个根结点联系起来&#xff0c;这个根节点没有前驱…

电子科技大学链时代工作室招新题C语言部分---题号E

1. 题目 这道题大概的意思是说&#xff0c;一座城市中被埋了许多雷&#xff08;用一个只含0和1的字符串表示城市&#xff0c;1代表有雷&#xff0c;0代表无雷&#xff09;。 你作为一个排雷兵&#xff0c;需要花最少的钱引爆所有的雷来使城市中不再有雷&#xff08;太逆天了&a…

【小白刷leetcode】第15题

【小白刷leetcode】第15题 动手刷leetcode&#xff0c;正在准备蓝桥&#xff0c;但是本人算法能力一直是硬伤。。。所以做得一直很痛苦。但是不熟练的事情像练吉他一样&#xff0c;就需要慢速&#xff0c;多练。 题目描述 看这个题目&#xff0c;说实在看的不是很懂。索性我们直…