> 文档中心 > 「Acwing算法合集」

「Acwing算法合集」


力扣算法系列文章


一、判断子序列

题目如下:

给定一个长度为 n 的整数序列 a1,a2,…,an 以及一个长度为 m 的整数序列 b1,b2,…,bm。
请你判断 a 序列是否为 b 序列的子序列。
子序列指序列的一部分项按原有次序排列而得的序列,例如序列 {a1,a3,a5} 是序列 {a1,a2,a3,a4,a5} 的一个子序列。

输入格式
第一行包含两个整数 n,m。
第二行包含 n 个整数,表示 a1,a2,…,an。
第三行包含 m 个整数,表示 b1,b2,…,bm。

输出格式
如果 a 序列是 b 序列的子序列,输出一行 Yes。
否则,输出 No。

数据范围
1≤n≤m≤105,
−109≤ai,bi≤109
输入样例:
3 5
1 3 5
1 2 3 4 5
输出样例:
Yes

代码如下:

import java.util.Scanner;public class Main {    public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int[] arr1 = new int[n]; int[] arr2 = new int[m]; for(int i = 0; i < n; ++i){     arr1[i] = sc.nextInt(); } for(int i = 0; i < m; ++i){     arr2[i] = sc.nextInt(); } int p1 = 0; for(int i = 0; i < m; ++i){     if(p1 < n && arr1[p1] == arr2[i]){  ++p1;     } } if(p1 == n) {     System.out.println("Yes"); }else{     System.out.println("No"); }    }}

运行结果:

在这里插入图片描述


二、二进制中1的个数

题目如下:

给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。

输入格式
第一行包含整数 n。
第二行包含 n 个整数,表示整个数列。

输出格式
共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。

数据范围
1≤n≤100000,
0≤数列中元素的值≤109
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2

代码如下:

import java.util.*;public class Main{    public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); while(n -- > 0){     int num = sc.nextInt();     int cnt = 0;     while(num != 0){  int rightOne = num & (-num);  num ^= rightOne;  cnt++;     }     System.out.print(cnt + " "); }    }}

运行结果:

在这里插入图片描述


三、区间

题目如下:

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。
现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。
接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。

输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含两个整数 x 和 c。
再接下来 m 行,每行包含两个整数 l 和 r。

输出格式
共 m 行,每行输出一个询问中所求的区间内数字和。

数据范围
−109≤x≤109,
1≤n,m≤105,
−109≤l≤r≤109,
−10000≤c≤10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5

代码如下:

import java.util.*;public class Main {    public static class Pair{ int first; int second; public Pair(int o1, int o2){     this.first = o1;     this.second = o2; }    }    public static final int N = 300010;    public static int n;    public static int m;    public static int[] CoordinateAxes = new int[N];    public static int[] sum = new int[N];    public static List<Integer> alls = new ArrayList<>();    public static List<Pair> add = new ArrayList<>();    public static List<Pair> query = new ArrayList<>();    public static int unique(List<Integer> list) { int j = 0; for (int i = 0; i < list.size(); i++) {     if (i == 0 || list.get(i) != list.get(i - 1)) {  list.set(j, list.get(i));  j++;     } } return j;    }    public static int find(int x){ int l = 0; int r = alls.size() - 1; while(l < r){     int mid = l + ((r - l) >> 1);     if(alls.get(mid) >= x){  r = mid;     }else{  l = mid + 1;     } } return r + 1;    }    public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); for(int i = 0; i < n; ++i){     int x = sc.nextInt();     int c = sc.nextInt();     add.add(new Pair(x, c));     alls.add(x); } for(int i = 0; i < m; ++i){     int l = sc.nextInt();     int r = sc.nextInt();     query.add(new Pair(l, r));     alls.add(l);     alls.add(r); } Collections.sort(alls); int unique = unique(alls); alls = alls.subList(0, unique); for(Pair item : add){     int x = find(item.first);     CoordinateAxes[x] += item.second; } for(int i = 1; i <= alls.size(); ++i){     sum[i] = sum[i - 1] + CoordinateAxes[i]; } for(Pair item : query){     int l = find(item.first);     int r = find(item.second);     System.out.println(sum[r] - (l -1 < 0 ? 0 : sum[l - 1])); }    }}

运行结果:

在这里插入图片描述


四、区间合并

题目如下:

给定 n 个区间 [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。

输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。

输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。

数据范围
1≤n≤100000,
−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3

代码如下:

import java.util.*;public class Main {     public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] arr = new int[n][2]; for(int i = 0; i < n; ++i){     arr[i][0] = sc.nextInt();     arr[i][1] = sc.nextInt(); } final int[][] merge = merge(arr); System.out.println(merge.length);    }     public static int[][] merge(int[][] intervals) { int len=intervals.length; if (len==0)     return new int[0][2]; Arrays.sort(intervals, new Comparator<int[]>() {     public int compare(int[] o1, int[] o2) {  return o1[0]-o2[0];     } }); List<int[]> list=new ArrayList<int[]>(); for(int i=0;i<len;i++){     int start=intervals[i][0];     int end=intervals[i][1];     if(list.size()==0 || start > list.get(list.size()-1)[1]){  list.add(new int[]{start,end});     }else {  list.get(list.size()-1)[1]=Math.max(end,list.get(list.size()-1)[1]);     } } return list.toArray(new int[list.size()][]);    } }

运行结果:

在这里插入图片描述