数据结构与算法-双指针算法

一、双指针类型

1、普通双指针

两个指针往同一个方向移动(普通双指针处理后的array元素的相对位置不会发生改变)

//1 首先初始化两个指针
int i = 0, j = 0;
while(j<array.length){
	//如果array[j] 是我们想要的值 ,那么让array[i] = array[j] 再让 i++;
	//否则的话 让i 指针固定住,遍历 j 指针
}
处理过的     不需要的数据   未处理的数据
0      	i               j        n
  ----------------------->           

2、对撞双指针

两个指针面对面移动(对撞双指针经过处理后array元素的相对位置可能会发生改变)

//一般的解题思路是
//1 初始化两个指针
int i = 0 , j = array.length - 1;
//2 两个指针相向而行
while(i <= j){
	//1 基于 array[i] 和 array[j] 进行具体情况的操作
	//2 然后至少要移动一个指针
}

处理过的     未处理的数据    处理过的
0      	i               j        n
  ---->                  <------        

3、快慢双指针

慢指针+快指针

二、双指针题型

1.leetcode 141 环形链表

给定一个链表,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
示例 1:
在这里插入图片描述
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
在这里插入图片描述
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
在这里插入图片描述
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。

解答:

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null)
            return false;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast)
                return true;
        }
        return false;
    }
}

2.leetcode 881 救生艇

第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)

示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)

示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
提示:
1 <= people.length <= 50000
1 <= people[i] <= limit <= 30000

解答:

class Solution {
    public int numRescueBoats(int[] people, int limit) {
        //首先原地排序
        Arrays.sort(people);
        //定义两个指针,对撞
        int i = 0, j = people.length - 1, res = 0;
        while (i <= j) {
        	//如果左右的两个体重 <= limit的时候 左指针才移动,
            if (people[i] + people[j] <= limit)
                i += 1;
            //右指针不管什么情况 都要向左移动
            j -= 1;
            //记录结果。
            res += 1;
        }
        return res;
    }
}

三、推广

云数据库RDS MySQL 版是全球最受欢迎的开源数据库之一,作为开源软件组合 LAMP(Linux + Apache + MySQL + Perl/PHP/Python) 中的重要一环,广泛应用于各类应用场景。
点击查看->>> 云数据库新年钜惠,新用户1折起,爆款5-8折,MySQL 1年仅需19.9元.
云服务器ECS
云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的云计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。专业的售前技术支持,协助您选择最合适配置方案
点击查看->>> 弹性计算10年深厚技术积淀,技术领先、性能优异、 稳如磐石.
短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%;国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。
点击查看->>> 短信服务新用户 0元免费试用.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值