写点什么

七日算法先导(二)——双指针

作者:秋名山码民
  • 2022 年 8 月 02 日
  • 本文字数:1401 字

    阅读完需:约 5 分钟

作业解答

昨天作业都比较简单,我挑几个小伙伴反应的疑惑说一下:增量元素之间的最大差值


int max(int a,int b){        return a>b?a:b;}int min(int a,int b){    return a<b?a:b;}
int maximumDifference(int* nums, int numsSize){ int maxS = -1;//最大差为-1 int minS = nums[0];//最小元素为nums[0]
//遍历数组,时间复杂度为O(n) for(int i = 1; i<numsSize;i++){ int sub = nums[i] -minS; if(sub > 0){ //更新 maxS = max(sub,maxS); }
//更新最小 minS = min(nums[i],minS); } return maxS;}
复制代码


其中这个最小元素为啥要初始化为 nums[0],简单的来说我们是从左到右遍历数组的,nums[i]每次减 minS,假设 minS 初始化为其他值,那么可能出现跳过第一个值或者初始值不在数组中的情况


674. 最长连续递增序列 - 力扣(LeetCode)


class Solution {    public int findLengthOfLCIS(int[] nums) {        //双指针(假的滑动窗口)        if(nums == null || nums.length == 0)    return 0;                int i = 0, j = 1, ans = 1;        while(j < nums.length){            if(nums[j] > nums[j-1]){                j++;            }else{                i = j;                j++;            }            ans = Math.max(ans, j-i);        }        return ans;    }}
复制代码


昨天这个题,就可以考虑用双指针来写,当然昨天的暴力解法也是正确的。


思路:当 nums[j] > nums[j-1] 的时候就是左边大于本身满足条件,j++否则的话,就不连续了,i 变为 j 最后比较最长序列,ans,和,j-i 中选取最大的

概念

参考我之前写过的这篇文章:从0到1入门双指针


入门是不够的,下面我们来看双指针的三种情况:


  1. 数组相向追赶

  2. 数组相向逼近

  3. 链表快慢指针(有点难)

数组相向追赶

俩个指针,i 可以一直往前走,但是 j 只有当满足条件的时候才往前走

数组相向逼近

一般来说,俩个指针从数组的俩端开始,不断的去 check 是否满足条件,根据不同的条件,来选择是左指针自增,还是右指针自减

链表快慢指针

快慢指针,顾名思义,定义俩个指针,一个指针可以走的很快,另一个相对走的较慢,当快指针走到链表结尾,慢指针对应的节点,获取一些信息,从而解决一些问题。


slow = slow.next;fast = fast.next.next;
复制代码


假设快慢指针原来都指向头结点,这样的话,fast 指针移动速度就是 slow 指针的两倍,这是很有用的设计


例如:找到链表中点


int length = 0;ListNode node = head;// 遍历一遍链表得到链表长度while(node!=null){    node = node.next;    length ++;}// 根据得到的链表长度,可以遍历长度/2次来找到终点ListNode centerNode = head;for(int i=0;i<length/2-1;i++){    centerNode = centerNode.next;}
复制代码


上面的方法遍历了 N+N/2 次,且代码略显复杂,最后遍历长度/2 次时,要注意 centerNode 节点实际上是中点的下一个节点,所以可以让遍历次数-1 来得到中点.


下面是使用了快慢节点的做法:


// 快慢指针起点相同ListNode slow = head;ListNode fast = head;while(fast.next!=null && fast.next.next!=null){    slow = slow.next;    // 快指针移动速度为慢指针两倍    fast = fast.next.next;}// 当快指针到达链表表尾时,此时慢指针指向链表中点ListNode centerNode = slow;
复制代码

刷题巩固

双调序列判断子序列排列排序俩数之和||

发布于: 刚刚阅读数: 4
用户头像

卷不死,就往…… 2021.10.19 加入

2019NOIP退役成员,华为云享专家,阿里云专家博主,csdn博主,努力进行算法分享,有问题欢迎私聊

评论

发布
暂无评论
七日算法先导(二)——双指针_8月月更_秋名山码民_InfoQ写作社区