如何巧妙地利用双指针求最小路径?
在计算机科学中,双指针技巧(Two Pointers Technique)是一种常用的算法技巧,尤其适用于处理有序数组或链表中的问题。它通过使用两个指针(或索引)在数据结构上进行遍历,从而达到优化时间复杂度的目的。在求解最小路径问题时,双指针技巧也可以大显身手。下面是一个使用双指针技巧求解最小路径的示例。
假设你有两个有序数组 A
和 B
,需要找到两个元素,一个来自 A
,一个来自 B
,使得它们的和最接近目标值 target
。这是一个典型的双指针应用场景。
双指针算法步骤
-
初始化指针:
- 一个指针
i
指向数组A
的起始位置(即0
)。 - 另一个指针
j
指向数组B
的末尾位置(即len(B) - 1
)。
- 一个指针
-
遍历数组:
- 计算当前指针所指位置的两个元素的和
current_sum = A[i] + B[j]
。 - 比较
current_sum
与target
的差值,并更新最小差值及其对应的元素对。 - 根据
current_sum
与target
的比较结果,移动指针:- 如果
current_sum
小于target
,则移动i
指针向右(即i++
),以增加和的值。 - 如果
current_sum
大于target
,则移动j
指针向左(即j--
),以减小和的值。
- 如果
- 重复上述步骤,直到两个指针交错。
- 计算当前指针所指位置的两个元素的和
代码示例
解析
- 初始化:指针
i
从数组A
的起始位置开始,指针j
从数组B
的末尾位置开始。 - 遍历和比较:通过使用双指针,逐步缩小搜索范围,以找到最接近目标值的元素对。
- 时间复杂度:由于每次循环中至少有一个指针会移动,因此总的时间复杂度为
O(n + m)
,其中n
和m
分别是数组A
和B
的长度。
这种方法不仅高效,而且简单明了,非常适合处理类似的问题。
话不多说,来上真题:
区分黑球与白球[中等]
题目:
桌子上有 n
个球,每个球的颜色不是黑色,就是白色。
给你一个长度为 n
、下标从 0 开始的二进制字符串 s
,其中 1
和 0
分别代表黑色和白色的球。
在每一步中,你可以选择两个相邻的球并交换它们。
返回「将所有黑色球都移到右侧,所有白色球都移到左侧所需的 最小步数」。
示例 1:
输入:s = "101"
输出:1
解释:我们可以按以下方式将所有黑色球移到右侧:
- 交换 s[0] 和 s[1],s = "011"。
最开始,1 没有都在右侧,需要至少 1 步将其移到右侧。
示例 2:
输入:s = "100"
输出:2
解释:我们可以按以下方式将所有黑色球移到右侧:
- 交换 s[0] 和 s[1],s = "010"。
- 交换 s[1] 和 s[2],s = "001"。
可以证明所需的最小步数为 2 。
示例 3:
输入:s = "0111"
输出:0
解释:所有黑色球都已经在右侧。
提示:
1 <= n == s.length <= 105
s[i]
不是'0'
,就是'1'
。
题目分析:
题目意思就是把字符串内的所有1都放到右边,所有0都放到左边,那这里的话我们就可以利用一个双指针去遍历整个字符串s,相当于是快速排序的算法思路,左边去找1,找到之后停下;同时右边去找0,找到之后停下;然后两个指针指的元素交换位置,此时需要的步数就是 尾指针re减去头指针pr,即 re-pr;直到遍历到re==pr为止。
代码实现:
总结:
这段代码的核心思想是通过双指针将字符串按照交替模式中 ‘0’ 和 ‘1’ 的位置进行交换,以达到最小步数的目的。详细解释如下:
- 将输入字符串 s 转换为列表 s,并获取字符串的长度 n。
- 如果输入字符串长度为 1,则直接返回 0。
- 初始化两个指针 pr 和 re,分别指向字符串的开头和末尾。
- 初始化变量 ans 记录最小步数。
- 在 pr < re 的情况下,开始一个 while 循环:
- 内层 while 循环将 pr 指向的元素为 ‘0’ 且 pr 小于 re 时,pr 向后移动,直到找到第一个不为 ‘0’ 的位置。
- 内层 while 循环将 re 指向的元素为 ‘1’ 且 re 大于 pr 时,re 向前移动,直到找到第一个不为 ‘1’ 的位置。
- 将 ans 增加 re - pr,即当前位置需要交换的步数。
- 交换 pr 和 re 指向的元素,然后将 pr 前进一步,re 后退一步。
- 最终返回 ans,即将字符串转换为 0101… 这种交替模式所需的最小步数。
- 点赞
- 收藏
- 关注作者
评论(0)