双指针

双指针

系统的学了一下。

链上问题:

一般是用一个快指针 f,一个慢指针 s

这里默认起始时 \(f\gets head,s\gets head\)

判环:

每次:\(f\gets f+2,s\gets s+1\)

若前进后 \(f=s\) 则有环。

相当于追及。

求环的起点:

先每次:\(f\gets f+2,s\gets s+1\)

\(f=s\) 后:

\(s\gets head\)

每次:\(f\gets f+1,s\gets s+1\)

\(f=s\)\(f\) 即为起点。

证明:

第一次 \(f=s\) 时:

\[len_f=2len_s \]

\[\because len_f-len_s=\text{环长} \]

\[\therefore len_s=\text{环长} \]

设相遇点距起点 \(x\)

显然第二次 \(f=s\) 时,\(s=f=\text{起点}\)\(new\_len_s=new\_len_f=\text{环长}-x\)

画图感性理解一下

求中点:

每次:\(f\gets f+2,s\gets s+1\)

\(f=tail\)\(s=mid\)

求终点前 \(k\) 个:

起始:\(f\gets head+k,s\gets head\)

每次:\(f\gets f+1,s\gets s+1\)

\(f=tail\)\(s=tail-k\)

感觉也就求、判环有点用。

真·双指针

两个指针:\(l,r\)

指针表示当前状态,根据当前状态转移(一般直接贪心)

显然,用双指针的问题必须满足:

  1. \(>\)\(<\) 定义(值 \(v\) 可比)——可比性:

    就是对于一种状态,可以 \(\operatorname{O}(1)\) 判断如何修改区间。

  2. 对于 \(l_1,r_1,l_2,r_2,l_3,r_3\)\(v_1<v_2,v_2<v_3\) 时,\(v_1<v_3\)\(>\) 同理,\(v_i\)\(l_1,r_1\) 的值)——传递性

名字我瞎起的,以下就这么称呼。

类似二分答案满足的性质(因为二分也是双指针)

例子:

  1. 二分查找:

    给定一个升序序列 \(a\),求第一个 \(\le x\) 的数。

    状态 \(l,r\) 的值 \(v=a_{mid}\)

    初始 \(l=1,r=n\)

    可比性:对于 \(l,r\),有 \(v<x\)\(l\gets mid+1\),否则 \(r\gets mid-1\)

    传递性:对于 \(l_1,r_1,l_2,r_2,l_3,r_3\)\(v_1<v_2,v_2<v_3\)\(v_1<v_3\)

  2. 两数之和:

    给定一个升序序列 \(a\) 和自然数 \(k\),求其中两个数 \(x,y\) 满足 \(x+y=k\)

    状态 \(l,r\) 的值 \(v=a_l+a_r\)

    初始 \(l=1,r=n\)

    可比性:对于 \(l,r\),有 \(v<x\)\(l\gets l+1\),否则 \(r\gets r-1\)

    传递性:对于 \(l_1,r_1,l_2,r_2,l_3,r_3\)\(v_1<v_2,v_2<v_3\)\(v_1<v_3\)

  3. Bovine Genomics

    状态 \(l,r\) 的值 \(v=[l\text{ 到 }r\text{ 满足题意(均不相同)}]\)

    初始 \(l=r=1\)

    可比性:对于 \(l,r\),有 \(v=1\)\(l\gets l+1\),否则 \(r\gets r+1\)

    传递性:对于 \(l_1,r_1,l_2,r_2,l_3,r_3\)\(v_1<v_2,v_2<v_3\)\(v_1<v_3\)\(0<1\)

posted @ 2023-11-15 21:42  xrlong  阅读(17)  评论(0编辑  收藏  举报