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>