不要哀求,学会争取,若是如此,终有所获.|

凪风sama

园龄:1年11个月粉丝:18关注:6

Acwing 800.数组元素的目标和,双指针初步

Acwing 800.数组元素的目标和

给定升序的有序数组A(长度为n),B(长度为m)以及目标值x,求出满足A[i]+B[j]=x的数对(i,j),题目保证仅有 唯一解

输入样例:

4 5 6
1 2 4 7
3 4 6 8 9

输出样例:

1 1

双指针来做
定义指针i,j,其中i指向A,j指向B,且i = 0,指向A的首元素,j = m-1,指向B的末尾元素。

给出以下代码

for(int i=0,j=m-1;i<n;i++)
{
while(A[i]+B[j]>x&&j>=0)j--;
if(A[i]+B[j]==x)
{
cout<<i<<" " <<j;
break;
}
}

我们来分析以下,在仅有唯一解以及递增序列这两个前提下

不妨定义这样一种关系j=f(i),其意思即为对于每个i,f(i)为令A[i]+B[j]>x的最小j,用题目输入举例

1 2 4 7
3 4 6 8 9
下标从1开始

i = 1 , 满足f的 j = 3
i = 2 , 满足f的 j = 2
i = 3, 满足f的 j = 1
i = 4, 满足f的 j = 1

显然,由于递增序列的特性,随着 i 的增加,其满足A[i]+B[j]>=x的最小 j 是在不断减小或者说单调不减的。

而如此来定义i以及j,每次得到的(i,j) 都是最有可能的数对取值,而我们所要做的就是遍历这些取值来找到那个唯一的等于解。
实际上我们这里的while退出条件为A[i]+B[j]>x,也就是说以A[i]+B[j]<=x来作为分界。每一次退出循环,得到的数对(i,j1)即为j=f(i) 得来的i以及j1 = j-1,这样得到的(i,j1)即为边界A[i]+B[j]>x的左侧,仅有两种可能,即小于或者等于,枚举出等于的那种情况即可。

感谢acwing文章作者AcWing 800. 双指针算法本质剖析: 从起源, 到优化, 到双指针, 到变形 - AcWing),这篇文章很好的打开了思路,严谨有趣

最后,给自己提个醒,双指针类的题目,要找出其对应的单调性,使得两个指针 i ,j 不回退,一直前进(或者后退),从而优化时间复杂度到O(n)

本文作者:凪风的博客

本文链接:https://www.cnblogs.com/CrescentWind/p/17772520.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   凪风sama  阅读(25)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示