专题一双指针
1.移动0
数组分块
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下 原地 对数组进行操作。

cur扫描数组。
dest分界扫描过的前非0元素与后0元素。
分割形成的原理:
cur :
遇0cur++
非0des++ 交换 cur++
拓展来看:
区域数据的划分。
2.双0复写
从后写入
给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过 该数组长度的位置写入元素。请对输入的数组 就地进行上述修改,不要从函数返回任何东西。

1.cur扫描 实现dest、cur的定位
cur = 0,dest = -1;
cur非零 dest++ 若dest>=size-1break ; cur++;
cur为零 dest+=2 若dest>=size-1break ; cur++;
2.特殊情况处理(des越界)

size-1 = 0; cur--; dest -= 2;
为什么会有特殊情况?
第二步的逻辑假设与第一步的dest+=2相关联。
3.从后往前复写
cur至最后一个要写的数
dest从后往前:
cur为0 dest为0 dest-- dest为0 dest-- cur--
cur非零 交换 dest-- cur--
反思:
下标+=2就可能越界像指针->next->next一样 可能在中途出现空指针。
3.数组元素循环判断 快乐数
尾循环
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

快慢指针体现于 每次取各个位的平方和的次数若n == 19
那么s = 1^2 + 9^2 == 82; f = 8^2 + 2^2; 此后f按照自身数来进行"两步" s按照自身数来进行"一步"。 ↓
//为什么不能按照s来呢? 答案:f的相对位移逐增。
题眼:"1"的循环看待 快慢指针的定义
4.数组水桶问题
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
**说明:**你不能倾斜容器。

左右聚拢的依据:(本质为单调性的使用)

双指针向内聚拢 更新最大值。
5.有效三角形个数
使用sort快排减少三角形决断次数 若:a <= b <= c 那么满足a+b>c即可!

cur>=2
l < r
①a + b > c sum += right - left;,right-- //中间部分全大于
②a + b <= c left++; //left向中间聚拢找可能存在的
反思:主要利用单调性来简化三角形次数的判断
练习
要求:打草画清晰图 结构化 了解双指针的内涵
购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。
示例 1:
输入:price = [3, 9, 12, 15], target = 18
输出:[3,15] 或者 [15,3]
示例 2:
输入:price = [8, 21, 27, 34, 52, 66], target = 61
输出:[27,34] 或者 [34,27]
6.三数和
前言:基于两数和进行。
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
**注意:**答案中不可以包含重复的三元组。

固定 i 在i的左侧利用双指针来寻找与-numsi相等的和值 。
去重:内部去重 外部去重