当前位置: 首页 > wzjs >正文

单位网站 方案搜索引擎技巧

单位网站 方案,搜索引擎技巧,做海报有什么借鉴的网站,哪个网站可以做视频本章先分享关于优选算法的双指针的思路: 主要是以题目来展示常见使用双指针的思路。 ps: 双指针做法:不要被表面所迷惑,它其实是通过用一个数组的下标来充当指针 数组分两块:是⾮常常⻅的⼀种题型,主要就是根据⼀种…

本章先分享关于优选算法的双指针的思路:

主要是以题目来展示常见使用双指针的思路。

ps:

双指针做法:不要被表面所迷惑,它其实是通过用一个数组的下标来充当指针

数组分两块:是⾮常常⻅的⼀种题型,主要就是根据⼀种划分⽅式,将数组的内容分成左右两部分。这种类型的题,⼀般就是使⽤「双指针」来解决
 

OJ(一)

283. 移动零 - 力扣(LeetCode)

1)题目展示

 2)解法思路:

数组分两块:一边非0,一边0,可以使用双指针法。

1.定义两个指针:

cur:从左到右扫描数据,来遍历数组

dest:已处理的区间内,非零元素的最后一个位置。

由下面我们可以看出:

分为三个区间:

[0,dest][]dest+1,cur-1][cur,n-1]

非0            0                 未处理

过程

具体做法:

1.cur遇到0,cur++

2.cur遇到非零元素:swap(dest+1,cur),cur++

代码:

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

OJ(二)

1089. 复写零 - 力扣(LeetCode)

1)题目展示:

2)解法思路:

1.双指针法:

如果「从前向后」进⾏原地复写操作的话,由于 0 的出现会复写两次,导致没有复写的数「被覆盖掉」。因此我们选择「从后往前」的复写策略。

但「从后向前」复写的时候,我们需要找到「最后⼀个复写的数」,因此我们的⼤体流程分两步:

i. 先找到最后⼀个复写的数;

ii. 然后从后向前进⾏复写操作

总结:

1.先根据“异地”操作,然后再进行双指针的“就地”操作

2.先找到最后一个复写的数:

双指针算法:

1)先判断cur的值

2)决定dest是走一步还是两步(0两步,非0一步)

3)判断dest是否已经到了结束位置

4)cur++

3.  然后从后向前进⾏复写操作。

1)i. 判断 cur 位置的值:

1. 如果是 0 : dest 以及 dest - 1 位置修改成 0 , dest -= 2 ;

2. 如果⾮零: dest 位置修改成 0 , dest -= 1 ;

2)cur-- ,复写下⼀个位置
 

4.越界处理:判断 dest 是否越界到 n 的位置

eg:1 0 2 3 0 0(会越界)

如果越界,执⾏下⾯三步:

1. n - 1 位置的值修改成 0 ;

2. cur 向移动⼀步(即cur--);

3. dest 向前移动两步(即dest-=2)
 

3)代码

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,dest=-1;int n=arr.size();while(cur<n){if(arr[cur]) dest++;else dest+=2;if(dest>=n-1) break;cur++;}if(dest==n){arr[n-1]=0;cur--;dest-=2;}while(cur>=0){if(arr[cur]){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
};

OJ快乐数(三)

202. 快乐数 - 力扣(LeetCode)

1)题目展示

2)解法思路

分析题目意思:

 看到这里,就与我们之前在数据结构里面OJ题写过的判断链表是否有环那题非常相似的。

那里,我们使用的是快慢指针的方法,实质也是双指针。

十道OJ题帮你深入认识链表-CSDN博客

所以,思路:

双指针的快慢指针:

1)慢指针每次向后移动一位

2.快指针每次向后移动两位

3.判断相遇时的值是否为1即可。

ps:其实这里不可能不成环的。(证明:鸽巢原理:n个巢,n+1个鸽,必有一个巢会有2只鸽子及以上)

3)代码

class Solution {
public:int GetNum(int n){int num=0;while(n){int ret=n%10;num+=ret*ret;n/=10;      }return num;}bool isHappy(int n) {int slow=n,fast=GetNum(n);while(slow!=fast){slow=GetNum(slow);fast=GetNum(GetNum(fast));}return fast==1;    }
};

OJ(四)

11. 盛最多水的容器 - 力扣(LeetCode)

1)题目展示

2)解法思路

解法1:暴力枚举(超时)即一个一个遍历去找

解法二:利用单调性,来进行使用双指针法解决

设两指针 left , right ,分别指向⽔槽板的最左端以及最右端,此时容器的宽度为 right - left 。由于容器的⾼度由两板中的短板决定,因此可得容积公式 : v = (j - i) * min(height[left], height[right])

为了下面的写法更加简洁,我们取高为h,宽为w,即V=h*w

下面我们就以题目的实例举例:

我们仔细观察会发现:

V=h*w,h由两板的短板决定

如果此时我们固定⼀个边界,改变另⼀个边界,⽔的容积会有如下变化形式:

--->容器的宽度⼀定变⼩。

---> 由于左边界较⼩,决定了⽔的⾼度。如果改变左边界,新的⽔⾯⾼度不确定,但是⼀定不会超

过右边的柱⼦⾼度,因此容器的容积可能会增⼤。

--->如果改变右边界,⽆论右边界移动到哪⾥,新的⽔⾯的⾼度⼀定不会超过左边界,也就是不会

超过现在的⽔⾯⾼度,但是由于容器的宽度减⼩,因此容器的容积⼀定会变⼩的。

因此:左边界和其余边界的组合情况都可以舍去。所以我们可以 left++ 跳过这个边界,继续去判断下⼀个左右边界

总结思路:

1.定义了left和right指针后,算出体积就可以舍去小的那个值了(即left的话就++,right的话就--)

2.高取小那个。

2.接着继续算体积,每次比较那个大就保留哪个。

3)代码

class Solution {
public:int maxArea(vector<int>& height) {int left=0,right=height.size()-1;int ret=0;while(left<right){int v=min(height[left],height[right])*(right-left);ret=max(ret,v);//移动指针if(height[left]<height[right]){left++;}else{right--;}}return ret;}
};

OJ(五)

611. 有效三角形的个数 - 力扣(LeetCode)

1)题目展示

2)解法思路

数学知识:

怎么才能构成三角形?

设a<=b<=c,那么要想构成三角形,则a+b>c

解法1:暴力枚举(弄三层for循环,再检查是否构成三角形,此时的时间复杂度就为O(n^3))

解法二:

1.我们先进行数组优化(即对数组进行排序)

2.接着利用单调性,使用双指针来解决:

1) 先固定最大的数  ----->O(N)

2)在最大数的左区间内,使用双指针法,快速通过符号构成三角形的数O(N)

若如果 nums[left] + nums[right] > nums[i] :

▪ 说明 [left, right - 1] 区间上的所有元素均可以与 nums[right] 构成⽐nums[i] ⼤的⼆元组

▪ 满⾜条件的有 right - left 种

如果 nums[left] + nums[right] <= nums[i] :

▪ 说明 left 位置的元素是不可能与 [left + 1, right] 位置上的元素构成满⾜条件的⼆元组

▪ left 位置的元素可以舍去, left++ 进⼊下轮循环

最后,时间复杂度为O(n^2)效率提高了.

3)代码

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());int n=nums.size();int ret=0;for(int i=n-1;i>=2;i--){int left=0,right=i-1;while(left<right){if(nums[left]+nums[right]>nums[i]){ret+=right-left;right--;}else{left++;}}}return ret;}
};

OJ(六)

LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

1)题目展示

2)解法思路

解法一:暴力枚举

解法二:利用单调性,使用双指针来找(跟上面的很像)

因为它已经排好序了,所以我们就省去了自己是排序那一步。

定义两个指针min(指向左边),max(右边)

若price[min]+price[max]>target,利用它的单调性,我们是不是就可以直接移动max--了?你想想你连最小的数都大于target了,其他是不是更加大于?

同样的道理:price[min]+price[max]<target ,直接min++。

当price[min]+price[max]==target时,就return  {price[left],price[right]};

3)代码

class Solution {
public:vector<int> twoSum(vector<int>& price, int target) {int left=0,right=price.size()-1;int sum=0;while(left<right){if(price[left]+price[right]>target){right--;}else if(price[left]+price[right]<target){left++;}else{return  {price[left],price[right]};}}return {};}
};

OJ(七)

15. 三数之和 - 力扣(LeetCode)

1)题目展示

2)解法思路

解法1:排序+暴力枚举+使用set(去重)

解法2:排序+双指针

1.排序

2.固定一个数a(我们从最左边第一个数先固定)

3.在固定的数的后面区间内,利用双指针,快速找到两个数的和等于-a

跟上面的题也是类似的,利用它的单调性,优化。

如果nums[left]+nums[right]>-a,即可直接right--;

nums[left]+nums[right]<-a,即可直接left++;(原因看上面的解析)

整体大概思路就完成了,

接下来我们来处理细节问题:

1.做到不漏:

解决:找到一种结果后,不要停,缩小区间,继续找

2.做到不重复

解决:

找到一种结果后,left和right都要跳过重复的数

当使用完一次双指针算法后,固定的数也要跳过重复的数。

此外,解决上面的问题的同时,还要注意避免越界的问题(代码中显示)

3)代码

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());int i=0;vector<vector<int>> ret;while(i<nums.size()){int left=i+1,right=nums.size()-1;while(left<right){if(nums[left]+nums[right]>(-nums[i])){right--;}else if(nums[left]+nums[right]<(-nums[i])){left++;}else{ret.push_back({nums[left],nums[right],nums[i]});left++;right--;1.防止越界while(left<right && nums[left-1]==nums[left]){left++;}2.防止越界while(left<right && nums[right+1]==nums[right])  {right--;}}}i++;3.防止越界        while(i<nums.size() && nums[i-1]==nums[i]){i++;}}return ret;}
};

OJ(八)

18. 四数之和 - 力扣(LeetCode)

1)题目展示

2)解法思路

解法1:排序+暴力枚举+set去重(4个循环)

解法2:排序+双指针

1.依次固定一个数a(我们从最左边第一个数开始)

2.在a的后面的区间内,使用“三数之和“找到数,使这三个数的和等于target-a即可

3.那么,根据上面的三数之和题目我们知道:

->固定一个数b

->在b的后面区间,利用双指针找到两个数,使这两个数的和等于target-a-b即可

整体大概思路就完成了,

接下来我们来处理细节问题:

1.做到不漏:

解决:找到一种结果后,不要停,缩小区间,继续找

2.做到不重复

解决:

找到一种结果后,left和right都要跳过重复的数

当使用完一次双指针算法后,固定的数也要跳过重复的数。

此外,解决上面的问题的同时,还要注意避免越界的问题(代码中显示)

3)代码

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(),nums.end());int n=nums.size();vector<vector<int>> ret;for(int a=0;a<n;){for(int b=a+1;b<n;){int left=b+1,right=n-1;long long aim=(long long)target-nums[a]-nums[b];while(left<right){if(nums[left]+nums[right]>aim){right--;}else if(nums[left]+nums[right]<aim){left++;}else{ret.push_back({nums[left],nums[right],nums[b],nums[a]});left++;while(left<right && nums[left]==nums[left-1]){left++;}right--;while(left<right && nums[right+1]==nums[right]){right--;}}}++b;while(b<n && nums[b]==nums[b-1]){b++;}}++a;while(a<n && nums[a]==nums[a-1]){a++;}}return ret;}
};

好了,双指针法专题到这里就分析完了,希望对你有所进步!

最后,到了本次鸡汤部分:

切勿轻言放弃,最好的东西,总会压轴出场!

http://www.dtcms.com/wzjs/148173.html

相关文章:

  • 重庆网站建设制作设计谷歌账号注册
  • 手机网站制作价格外贸seo软文发布平台
  • 福田做网站公司西安seo网站建设
  • 西乡县门户网站seo门户网站优化
  • wordpress源码安装教程seo推广话术
  • 电子商务网站建设与维护考试题打开百度一下你就知道
  • 中国著名十大vi设计案例家庭优化大师免费下载
  • wordpress站点一百数据卡不效果最好的推广软件
  • wordpress 首页添加链接地址seo页面排名优化
  • 网页的制作教程西安区seo搜索排名优化
  • 进一步提高政府网站建设水平安徽seo团队
  • 做网站论文研究方法怎么写谷歌搜索引擎下载安装
  • wordpress一键 centos太原网站优化公司
  • 广东上海专业网站建设公司哪家好营销app
  • 做网站服务器多大的好网页制作代码模板
  • 深圳电商网站制作企业网站制作教程
  • 做一级域名网站多少钱阿里巴巴seo排名优化
  • 上海网站建设制作公商品推广软文800字
  • 网站用的是什么字体收录网站的平台有哪些
  • 国家企业信息管理系统官网深圳seo关键词优化
  • 三亚市住房与城乡建设局网站衡水网站seo
  • 幼儿园网站设计代码google免费入口
  • 邓州市网站建设seo搜索引擎优化到底是什么
  • 阿里云 企业网站做网站需要什么技术
  • 专业的论坛网站建设简述网络营销与传统营销的整合
  • 平台推广网站排名十八未成年禁用免费app
  • 网站过程建设太原seo关键词优化
  • 域名怎么解析到服务器上济南网站优化
  • 将自己做的网站入到阿里云域名上推广营销
  • 如何把jQuery特效做网站背景邯郸网站建设优化