The core of double pointer: transfer the information expressed by the previous state pointer to the next state, so as to reduce unnecessary search
Template:
while(i < n && j < m){
if(checked(i, j)) i ++;
j ++;
}
Topic 1:
Given a sequence of integers a1,a2,..., an with a length of nn and a sequence of integers b1,b2,..., bm with a length of m.
Please judge whether the ^ a ^ sequence is a subsequence of ^ b ^ sequence.
Subsequence refers to the sequence obtained by arranging some items of the sequence in the original order. For example, sequence {a1,a3,a5}{a1,a3,a5} is a subsequence of sequence {a1,a2,a3,a4,a5}{a1,a2,a3,a4,a5}.
Input format
The first line contains two integers n,m.
The second line contains n integers, representing a1,a2,..., an.
The third line contains m integers, representing b1,b2,..., bm.
Output format
If the , a , sequence is a subsequence of , b , sequence, a line of , Yes is output.
Otherwise, output No.
Data range
1≤n≤m≤105
−1e9≤ai,bi≤1e9
Input sample:
3 5 1 3 5 1 2 3 4 5
Output example:
Yes
Problem solving ideas:
This question adopts the method of double finger needle, which is easy to think of
Template
while(i < n && j < m){
if(checked(i, j)) i ++;
j ++;
}
The template is applicable to j moving after continuous phase without being affected by any conditions (note that a[i] == b[j] in the judgment conditions, a[i] is affected by a[j])
The precondition of the algorithm is that a and b are ordered arrays. It is required to find each character in a and whether the order of characters in b exists
For each character a[i], if the character in b[j] is equal to the value, the next character in a is found
while(i < n && j < m){
if(a[i] == b[j]) i ++;
j ++;
}
In the whole process, the j pointer constantly scans the b array and moves backward, which is equivalent to constantly creating matching opportunities for the a array pointed to by the i pointer. Only when the matching is successful, the i pointer will move backward by one bit. When i==n, all matching is successful.
c++ :
#include <iostream> using namespace std; const int N = 100010; int n, m; int a[N], b[N]; int main(){ cin >> n >> m; for(int i = 0; i < n; i ++) scanf("%d", &a[i]); for(int i = 0; i < m; i ++) scanf("%d", &b[i]); int i = 0, j = 0; while(i < n && j < m){ if(a[i] == b[j]) i ++; j ++; } if(i == n) puts("Yes"); else puts("No"); }
python:
a = [0] * 100010 b = [0] * 100010 n, m = list(map(int, input().split(" "))) global a global b a = list(map(int, input().split(" "))) b = list(map(int, input().split(" "))) i, j = 0, 0 while(i < n and j < m): if(a[i] == b[j]): i += 1 j += 1 if(i == n): print("Yes") else: print("No")
Topic 2: targets and of array elements
Given two ordered arrays ^ A ^ and ^ B sorted in ascending order, and A target value ^ x.
Array subscripts start at 0.
Please find the number pair (i,j) satisfying , A[i]+B[j]=x ,.
The data is guaranteed to have a unique solution.
Input format
The first line contains three integers , n, m and x, representing the length of , A , the length of , B , and the target value , x.
The second line contains # n # integers representing array # A.
The third line contains # m# integers representing array # B.
Output format
A total of one line, including two integers # i # and # j.
Data range
The array length does not exceed 105105.
The elements in the same array are different.
1 ≤ array element ≤ 1e9
Input sample:
4 5 6 1 2 4 7 3 4 6 8 9
Output example:
1 1
Problem solving ideas:
In order to reduce loops, two pointers are used to ensure that all numbers that meet the requirements can be traversed;
The I pointer starts from the head of array A, where a[i] is the smallest;
The j pointer starts from the end of the B array, where b[j] is the largest;
When i = 0, judge the value of a[i] + b[j]. If it is greater than x, j --;
That is, the value of b[j] has been decreasing;
Then when the value of a[i] + b[j] is less than x for the first time, the sum of the number on the left of the j pointer and a[i] must be less than x; Then we can only increase the value of a[i];
So i + +;
From then on, repeat the cycle. If a[i] + b[j] is greater than x, reduce b[j] (equivalent to moving the j pointer to the left). On the contrary, increase a[i] (equivalent to moving the I pointer to the right)
In this way, it must be ensured that each two numbers that meet the requirements can be added again to judge whether the sum is equal to x.
c++
#include <iostream> using namespace std; const int N = 100010; int a[N], b[N]; int main() { int n ,m ,x; scanf("%d%d%d", &n, &m, &x); for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]); for (int j = 0; j < m; j ++ ) scanf("%d", &b[j]); for (int i = 0, j = m - 1; a[i] < x; i ++ ) { while(a[i] + b[j] > x) j --; if (a[i] + b[j] == x) { printf("%d %d", i, j); break; } } return 0; }
python:
N, M, X = map(int, input().split()) A = list(map(int, input().split())) B = list(map(int, input().split())) i = 0 j = 0 for i in range(N): while A[i] + B[j] > X: j -= 1 while A[i] + B[j] < X and j < len(B) - 1: j += 1 if A[i] + B[j] == X: break print(i, j)