two pointers思想 ---- 利用两个i, j两个下标,同时对序列进行扫描,以O(n)复杂度解决问题的一种思想, 如果能用这种思想解决问题,那么会大大降低程序的复杂度。

两个利用这个思想的例子:

1.

分析:

代码:

 while (i < j){
if (a[i] + a[j] == m){
printf("%d %d\n", i, j);
i++;
j++;
}
else if (a[i] + a[j] < m){
i++;
}
else{
j++;
}
}

2.

思路:

代码:

 int merge(int A[], int B[], int C[], int n, int m){
int i = , j = , index = ; // i指向A[0], j指向B[0]
while (i < n && j < m){
if (A[i] < B[j]){
C[index++] = A[i++];
}
else if (A[i] > B[j]){
C[index++] = B[j++];
}
else{
C[index++] = A[i++];
j++;
}
} while (i < n)
C[index++] = A[i++]; // 将序列A的剩余元素加入序列C
while (j < m)
C[index++] = B[j++]; // 将序列B的剩余元素加入序列C return index;
}

如果两个索引下标 i 和 j 指向的是同一个序列,那么这两个索引的移动方向一共有四种情况

1. i 和 j 都从0开始向(n - 1)移动,只是移动的速度不一样

2. i 和 j 都从(n - 1)开始向0移动,只是移动速度不一样

3. i 和 j 分别从0 和(n - 1)向中间移动(前面的例子1就是这种情况

4. i 和 j 都从序列的中间 n / 2 分别向0 和 n - 1两头移动

实战1:

前面用 二分法 解决过 PAT 的 B1030 题目,现在再用two pointers方法实现一遍:

              1030 完美数列 (25分)

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤10​5​​)是输入的正整数的个数,p(≤10​9​​)是给定的参数。第二行给出 N 个正整数,每个数不超过 10​9​​。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

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

输出样例:

8

思路:

注意点:

代码实现:

 #include <stdio.h>
#include <algorithm>
using namespace std; int a[];
int main()
{
freopen("in.txt", "r", stdin);
int n, p;
scanf("%d %d", &n, &p);
for (int i = ; i < n; i++){
scanf("%lld", &a[i]);
} sort(a, a + n); int i = , j = , count = ;
while (i < n && j < n){
// j不断右移,直到恰好不满足条件
while (j < n && a[j] <= (long long)a[i] * p){
count = max(count, j - i + );
j++;
}
i++; // i右移一位
} printf("%d\n", count); // 输出结果 fclose(stdin);
return ;
}

实战2:

求两个序列的中间数 (PAT A1029)

              1029 Median (25分)

Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S1 = { 11, 12, 13, 14 } is 12, and the median of S2 = { 9, 10, 15, 16, 17 } is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.

Given two increasing sequences of integers, you are asked to find their median.

Input Specification:

Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer N (≤2×10​5​​) is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.

Output Specification:

For each test case you should output the median of the two given sequences in a line.

Sample Input:

4 11 12 13 14
5 9 10 15 16 17

Sample Output:

13

思路:(两种方法)
法一:现将两个序列用two pointers方法混合成一个新的序列,再取出新序列的中间值
法一代码:
 #include <stdio.h>
#include <algorithm> using namespace std; int s1[], s2[];
int s3[]; // 混合函数
void merge(int A[], int B[], int C[], int n1, int n2){
int i = , j = , index = ;
while (i < n1 && j < n2){
if (A[i] < B[j]){
C[index++] = A[i++];
}
else if (A[i] > B[j]){
C[index++] = B[j++];
}
else{
C[index++] = A[i++];
j++;
}
} while (i < n1)
C[index++] = A[i++];
while (j < n2)
C[index++] = B[j++];
} int main()
{
freopen("in.txt", "r", stdin);
int n1, n2;
scanf("%d", &n1);
for (int i = ; i < n1; i++){
scanf("%d", &s1[i]);
} scanf("%d", &n2);
for (int i = ; i < n2; i++){
scanf("%d", &s2[i]);
} merge(s1, s2, s3, n1, n2);
if (n1 == && n2 == )
printf("0\n");
else
printf("%d\n", s3[(n1 + n2 - ) / ]); fclose(stdin);
return ;
}

法二:由于两个序列的长度都是已知的,所以中间值的位置就是确定的(m + n - 1) / 2,所以只需用two pointers方法不断对两个序列去最小值,直到最小值的位置是中间值的位置为止,这里要注意一点,最终输出的结果必须是s1[i]和s2[j]中的较小者。 法二代码:
 #include <stdio.h>
#include <algorithm>
using namespace std; const int inf = << ; int s1[], s2[]; int main()
{
freopen("in.txt", "r", stdin);
int n1, n2;
scanf("%d", &n1);
for (int i = ; i < n1; i++){
scanf("%d", &s1[i]);
} s1[n1] = inf; scanf("%d", &n2);
for (int i = ; i < n2; i++){
scanf("%d", &s2[i]);
}
s2[n2] = inf; // 中位数所在的位置下标
if (n1 == && n2 == ){
printf("0\n");
return ;
} int medianPos = (n1 + n2 - ) / ;
int i = , j = , index = ;
while (index < medianPos){
if (s1[i] < s2[j])
i++;
else
j++;
index++;
} if (s1[i] < s2[j])
printf("%d\n", s1[i]);
else
printf("%d\n", s2[j]); fclose(stdin);
return ;
}
 
 

 
1029 Median
1029位数
 

two pointers思想 ---- 利用两个i, j两个下标,同时对序列进行扫描,以O(n)复杂度解决问题的一种思想的更多相关文章

  1. 利用编辑距离(Edit Distance)计算两个字符串的相似度

    利用编辑距离(Edit Distance)计算两个字符串的相似度 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可 ...

  2. Serverless 是一种思想状态

    来源 | Serverless 公众号:作者 | Ben Kehoe:译者 | donghui 函数不是重点 如果你因为喜欢 Lambda 而选择 Serverless,你这样做的原因是错误的.如果你 ...

  3. 剑指Offer38 数组所有数字出现两次,只有两个出现了一次,找出这两个数字

    /************************************************************************* > File Name: 38_Number ...

  4. 在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编

    在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...

  5. 今天被 <!doctype html> 搞了两个小时,两个页面同样的样式,chosen右边的小箭头,一个上下居中对齐 一个居顶对齐。最后找到问题所在doctype

    今天被 <!doctype html> 搞了两个小时,两个页面同样的样式,chosen右边的小箭头,一个上下居中对齐 一个居顶对齐.最后找到问题所在doctype <-- 这个小箭头

  6. UBIFS文件系统简介 与 利用mkfs.ubifs和ubinize两个工具制作UBI镜像 (完整理解版本)

    UBI文件系统简介 在linux-2.6.27以前,谈到Flash文件系统,大家很多时候多会想到cramfs.jffs2.yaffs2等文件系统. 它们也都是基于文件系 统+mtd+flash设备的架 ...

  7. 利用 jQuery 来验证密码两次输入是否相同

    html <div class="row"> <div class="panel panel-info"> <div class= ...

  8. 创建4个线程,两个对j加一,两个对j减一(j两同两内)

    package multithread; public class MyThread { //j变量私有 private int j; //同步的+1方法 private synchronized v ...

  9. 利用mkfs.ubifs和ubinize两个工具制作UBI镜像

    转:http://blog.sina.com.cn/s/blog_9452251d01015z9h.html 有了mkfs.ubifs和ubinize两个工具后,就可以制作UBIFS镜像了,具体步骤如 ...

随机推荐

  1. elementui_day02

    Elementui_day02 1. maven多模块搭建 1.1 搭建多模块的好处 1. 方便维护(代码增加,拆分越细,越好维护) 2. 有些公共的内容(BaseDomain.BaseService ...

  2. C# WPF聊天界面(3/3)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF聊天界面(3/3) 阅读导航 本文背景 代码实现 本文参考 1.本文背景 系列文章 ...

  3. Python3标准库:bisect维护有序列表

    1. bisect维护有序列表 bisect模块实现了一个算法来向列表中插入元素,同时仍保持列表有序. 1.1 有序插入 下面给出一个简单的例子,这里使用insort()按有序顺序向一个列表中插入元素 ...

  4. Spring AOP-基于@AspectJ风格

    关于Spring AOP,可以去看看官方文档: https://docs.spring.io/spring-framework/docs/current/spring-framework-refere ...

  5. 【新人赛】阿里云恶意程序检测 -- 实践记录10.27 - TF-IDF模型调参 / 数据可视化

    TF-IDF模型调参 1. 调TfidfVectorizer的参数 ngram_range, min_df, max_df: 上一篇博客调了ngram_range这个参数,得出了ngram_range ...

  6. 【新人赛】阿里云恶意程序检测 -- 实践记录10.13 - Google Colab连接 / 数据简单查看 / 模型训练

    1. 比赛介绍 比赛地址:阿里云恶意程序检测新人赛 这个比赛和已结束的第三届阿里云安全算法挑战赛赛题类似,是一个开放的长期赛. 2. 前期准备 因为训练数据量比较大,本地CPU跑不起来,所以决定用Go ...

  7. Nginx配置HTTPS并将HTTP请求重定向到HTTPS

    个人博客 地址:https://www.wenhaofan.com/a/20190702214652 在阿里云获取免费的HTTPS证书 配置HTTPS之前首先需要拥有HTTPS证书,在阿里云可以获得域 ...

  8. TChart-图表编辑器的测试

    最近不知怎么的,想研究一下图表.先上效果图: 功能代码: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Class ...

  9. Docke-ce 安装

    Docker-ce 的安装 安装系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 添加docker镜像源 yum-con ...

  10. jvm编译器的优化

    1.对byte.short.char赋值时,若右边范围没有超过左边类型的最大表达范围则会自动隐式的加上(byte).(short).(char)强制转换:若右边范围超过了左边类型的最大表达范围则编译失 ...