数据结构和算法之双指针算法

本文详细介绍了双指针技术,包括快慢指针和对撞指针的概念、简单实现代码,并通过动画形式生动展示了它们在数组遍历中的工作过程。快慢指针常用于链表问题,而对撞指针适用于有序数组的查找和合并。此外,还提供了相关博客链接供深入探索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是双指针

双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。

换言之,双指针法充分使用了数组有序这一特征,从而在某些情况下能够简化一些运算。

2、快慢指针

1、说明

快慢指针也是双指针,但是两个指针从同一侧开始遍历数组,将这两个指针分别定义为快指针(fast)慢指针(slow),两个指针以不同的策略移动,直到两个指针的值相等(或其他特殊条件)为止,如fast每次增长两个,slow每次增长一个。

2、简单实现代码
const fast_slow_pointer = function(nums) {
	let fast = 0;
	let slow = 0;
	const len = nums.length;
	while(slow < len) {
		// 一些逻辑
		fast++;
		if(fast > len) {
			fast = 0;
			slow++;
		};
	};
};
3、演示动画

在这里插入图片描述

4、动画实现代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>快慢指针动画演示</title>
  <style>
    .canvas {
      margin: 50px auto;
      height: 800px;
      width: 1600px;
      background-color: #A5DAFA;
      border: 2px solid #000000;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .center {
      background-color: #fff;
      width: 1000px;
      height: 200px;
      display: flex;
      position: relative;
    }
    .empty_square {
      flex: 1;
      width: 200px;
      height: 200px;
      border: 2px solid #000;
    }
    .color_square {
      animation: run 5s linear;
      animation-iteration-count: 5;
      position: absolute;
      top: 0;
      left: 0;
      width: 200px;
      height: 200px;
      border: 2px solid #000;
      background-color: #02D980;
    }
    .down {
      animation: run 5s linear;
      animation-iteration-count: 5;
      position: absolute;
      top: -100px;
      font-size: 60px;
      text-align: center;
      width: 200px;
    }
    .up {
      animation: run 20s linear 5s;
      position: absolute;
      bottom: -100px;
      font-size: 60px;
      text-align: center;
      width: 200px;
    }
    @keyframes run {
      0%   { left: 0px;   }
      15%  { left: 200px; }
      25%  { left: 200px; }
      40%  { left: 400px; }
      50%  { left: 400px; }
      65%  { left: 600px; }
      75%  { left: 600px; }
      90%  { left: 800px; }
      100% { left: 800px; }
    }
  </style>
</head>
<body>
  <div class="canvas">
    <div class="center">
      <div class="down"><span class="down_text"></span></div>
      <div class="color_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="up"><span class="up_text"></span></div>
    </div>
  </div>
  <script>
    let i = 0;
    let j = 0;
    const down_text = document.querySelector('.down_text');
    const up_text = document.querySelector('.up_text');
    down_text.innerText = i;
    up_text.innerText = j;
    let down_run = window.setInterval(() => {
      i++;
      if(i > 4) i = 0;
      down_text.innerText = i;
    }, 1000)
    let up_run = window.setInterval(() => {
      j++;
      up_text.innerText = j;
      if(j > 4) {
        i = 0;
        j = 0;
        up_text.innerText = j;
        window.clearInterval(down_run)
        window.clearInterval(up_run);
      }
    }, 5000)
  </script>
</body>
</html>

3、对撞指针

1、说明

对撞指针是指在有序数组中,将指向最左侧的索引定义为左指针(left),最右侧的定义为右指针(right),然后从两头向中间进行数组遍历。

对撞数组适用于有序数组,也就是说当你遇到题目给定有序数组时,应该第一时间想到用对撞指针解题。

2、简单实现代码
const collisions_pointer = function(nums) {
  var left = 0;
  var right = nums.length - 1;
  while (left <= right) {
    left++;
    // 一些逻辑
    right--;
  }
}
3、演示动画

在这里插入图片描述

4、动画实现代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>对撞指针动画演示</title>
  <style>
    .canvas {
      margin: 50px auto;
      height: 800px;
      width: 1600px;
      background-color: #A5DAFA;
      border: 2px solid #000000;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .center {
      background-color: #fff;
      width: 900px;
      height: 100px;
      display: flex;
      position: relative;
    }
    .empty_square {
      flex: 1;
      width: 100px;
      height: 100px;
      border: 2px solid #000;
    }
    .l,
    .r {
      position: absolute;
      bottom: -100px;
      font-size: 60px;
      text-align: center;
      width: 100px;
    }
    .l {
      animation: l_run 5s linear;
      left: 0;
    }
    .r {
      animation: r_run 5s linear;
      right: 0;
    }
    @keyframes l_run {
      0%   { left: 0px;   }
      15%  { left: 100px; }
      25%  { left: 100px; }
      40%  { left: 200px; }
      50%  { left: 200px; }
      65%  { left: 300px; }
      75%  { left: 300px; }
      90%  { left: 400px; }
      100% { left: 400px; }
    }
    @keyframes r_run {
      0%   { left: 800px  }
      15%  { left: 700px; }
      25%  { left: 700px; }
      40%  { left: 600px; }
      50%  { left: 600px; }
      65%  { left: 500px; }
      75%  { left: 500px; }
      90%  { left: 400px; }
      100% { left: 400px; }
    }
  </style>
</head>
<body>
  <div class="canvas">
    <div class="center">
      <div class="l"><span class="l_text"></span></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="empty_square"></div>
      <div class="r"><span class="r_text"></span></div>
    </div>
  </div>
  <script>
    let i = 0;
    let j = 8;
    const l = document.querySelector('.l_text');
    const r = document.querySelector('.r_text');
    l.innerText = i;
    r.innerText = j;
    let l_run = window.setInterval(() => {
      i++;
      l.innerText = i;
    }, 1000)
    let r_run = window.setInterval(() => {
      j--;
      r.innerText = j;
      if(i > j) {
        i = 0;
        j = 8;
        l.innerText = i;
        r.innerText = j;
        window.clearInterval(l_run)
        window.clearInterval(r_run);
      }
    }, 1000)
  </script>
</body>
</html>

4、本人相关博客

力扣双指针的一些探索

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SmallTeddy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值