✔ ★算法基础笔记(Acwing)(一)—— 基础算法(20道题)【java版本】

news2024/12/1 0:36:55

基础算法

  • 一、快速排序
        • 1. 快速排序例题
        • 2. 第k个数( 快速选择 ) ✔ ✔1.31
            • ★快排二刷总结( 4点 )
  • 二、归并排序
        • 1. 归并排序模板题 ✔ ✔1.31
            • ★二刷总结
        • ★2. 逆序对的数量 ✔ ✔1.31
            • ★二刷总结
  • 三、二分
        • 1. 数的范围 ✔1.31
            • ★二刷总结(mid >= x 则是 输出最左边一个)
            • 第一个大于等于x的数 || 最后一个大于等于x的数
        • ★2. 数的三次方根 1e-8 ✔1.31
            • 二刷总结
  • 四、高精度
        • 1. 高精度加法 ✔1.31
          • BigInteger
        • 2. 高精度减法 ✔1.31
          • a.subtract(b)
        • 3. 高精度乘法
        • 4. 高精度除法 ✔(12分钟)2.1
  • 五、前缀和S与差分a
        • 1. 前缀和(2分钟)
        • 2. 子矩阵的和(7分钟)
        • 3. 差分(9分钟)
            • 二刷总结
        • 4. 差分矩阵(12分钟)
  • 六、双指针
        • ★ 1. 最长连续不重复子序列(20分钟)
            • 二刷总结(以空间换时间)
        • 2. 数组元素的目标和(7分钟)
        • 3. 判断子序列(8分钟)
  • 七、二进制
        • 1. 位运算算法(2分钟)
            • 返回n的最后一位1:lowbit(n) = n & -n
            • 一共有多少1 : while n = n ^(n & -n)或者 n -= n & -n
  • 八、离散化
            • 去重 V.erase(unique(.begin(),.end()),.end());
        • 1. ★ 区间和
            • 在草稿纸上列出需要几个数组,就清晰了
  • 九、区间合并
        • 1. 区间合并(7分钟)

一、快速排序

1. 快速排序例题

在这里插入图片描述
原题链接

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        quickSort(0,n-1,nums);
        for (int i=0; i<n; i++) {
            System.out.print(nums[i] + " ");
        }
    }
    
    public static void quickSort (int l,int r,int[] nums) {
        if(l>=r) {
            return;
        }
        int x = nums[(l+r)/2];
        int i = l - 1,j = r + 1;
        while (i < j) {
            while (nums[++i] < x);
            while (nums[--j] > x);
            if (i < j) {
                int t = nums[i];
                nums[i] = nums[j];
                nums[j] = t;
            }
        }
        quickSort(l,j,nums);
        quickSort(j+1,r,nums);
    }
}

2. 第k个数( 快速选择 ) ✔ ✔1.31

在这里插入图片描述
原题链接

import java.util.*;

public class Main {
    public static int k;
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        k = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        System.out.print(quickSortTheK_thNumber(0,n-1,nums));
    }
    
    public static int quickSortTheK_thNumber (int l,int r,int[] nums) {
        if (l >= r) {
            return nums[r];
        }
        int x = nums[(l+r)>>1];
        int i = l - 1, j = r + 1;
        while (i < j) {
            while (nums[++i] < x);
            while (nums[--j] > x);
            if (i < j) {
                int t = nums[i];
                nums[i] = nums[j];
                nums[j] = t;
            }
        }
        if (j < k-1) {
            return quickSortTheK_thNumber(j+1,r,nums);
        } else {
            return quickSortTheK_thNumber(l,j,nums);
        }
    }
}
★快排二刷总结( 4点 )
  1. if (l >= r) return;
  2. 没有等于号
  3. 交换有条件if (i < j) swap(q[i], q[j]);
  4. 基值要固定x = q[l + r >> 1]
  5. j最后的角标表示 l-j 是小于x的

二、归并排序

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
  1. 先分段
  2. 用一个额外数组,汇总两个分数组的排序

1. 归并排序模板题 ✔ ✔1.31

★二刷总结
  1. r = mid + 1
  2. while if
  3. temp 的k = 1
    a 的i = L

原题链接

在这里插入图片描述

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        merge_sort(0,n-1,nums);
        for (int i = 0; i < n; i++) {
            System.out.print(nums[i] + " ");
        }
    }
    
    public static void merge_sort (int l,int r,int[] nums) {
        if (l >= r) {
            return;
        }
        int mid = (l+r) >> 1;
        int i = l,j = mid + 1;
        merge_sort(l,mid,nums);
        merge_sort(mid+1,r,nums);
        
        int[] temp = new int[r - l + 1];
        int k = 0;
        while (i <= mid && j <= r) {
            if (nums[i] <= nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }
        while (i <= mid) {
            temp[k++] = nums[i++];
        }
        while (j <= r) {
            temp[k++] = nums[j++];
        }
        for (int q = l,p = 0; q <= r; q++) {
            nums[q] = temp[p++];
        }
    }
}

★2. 逆序对的数量 ✔ ✔1.31

原题链接

★二刷总结
  1. java中new不能全new

在这里插入图片描述

import java.util.*;

public class Main {
    public static long ans = 0;
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        numberOfReverseOrderPairs(0,n-1,nums);
        System.out.print(ans);
    }
    
    public static void numberOfReverseOrderPairs(int l,int r,int[] nums){
        if (l >= r) {
            return;
        }
        int mid = (l+r)>>1;
        int i = l,j = mid+1;
        numberOfReverseOrderPairs(l,mid,nums);
        numberOfReverseOrderPairs(mid+1,r,nums);
        int[] temp = new int[r-l+1];
        int k = 0;
        while (i <= mid && j <= r) {
            if (nums[i] <= nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
                ans += mid - i + 1;
            }
        }
        while (i <= mid) {
            temp[k++] = nums[i++];
        }
        while (j <= r) {
            temp[k++] = nums[j++];
        }
        for (int q = l,p = 0; q <= r; q++) {
            nums[q] = temp[p++];
        }
    }
}

三、二分

1. 数的范围 ✔1.31

原题链接

★二刷总结(mid >= x 则是 输出最左边一个)
第一个大于等于x的数 || 最后一个大于等于x的数

mid < x 则是 往右

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        
        for (int i = 0; i < m; i++) {
            int x = scanner.nextInt();
            
            int p = 0,q = 0;
            int l = 0,r = n-1;
            while (l < r) {
                int mid = (l+r)>>1;
                if (nums[mid] < x) {
                    l = mid+1;
                } else {
                    r = mid;
                }
            }
            p = r;
            l = 0;
            r = n-1;
            while (l < r) {
                int mid = (l+r+1)>>1;
                if (nums[mid] <= x) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }
            q = r;
            if (nums[q] != x) {
              System.out.println(-1 + " " + -1); 
            } else {
                System.out.println(p + " " + q);
            }
        }
    }
}

★2. 数的三次方根 1e-8 ✔1.31

原题链接
在这里插入图片描述

二刷总结
  1. 精确度是1e-8
  2. l或者r直接等于mid
import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        double n = scanner.nextDouble();
        double l = (double)-1e5;
        double r = 1e5*1.0;
        while (r - l > 1e-8) {
            double mid = (l+r)/2;
            if (mid * mid * mid <= n) {
                l = mid;
            } else {
                r = mid;
            }
        }
        System.out.printf("%.6f",l);
    }
}

四、高精度

1. 高精度加法 ✔1.31

原题链接
二刷:

  1. 因为先计算小数,所以先把小数入 vector
  2. 存放的时候先存放小数,这样i 一个角标就可以作为两个数的运算位置进行运算,如果相反的话,因为需要先计算最小值,那么就需要用两个角标指向最小值了
    在这里插入图片描述
BigInteger
import java.io.BufferedInputStream;
import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        BigInteger a = scanner.nextBigInteger();
        BigInteger b = scanner.nextBigInteger();
        System.out.println(a.add(b));
        scanner.close();
    }

}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.next();
        String s2 = scanner.next();
        List<Integer> A = new ArrayList<>(s1.length());
        List<Integer> B = new ArrayList<>(s2.length());
        for (int i = s1.length() - 1; i >= 0; i--) A.add(s1.charAt(i) - '0');
        for (int i = s2.length() - 1; i >= 0; i--) B.add(s2.charAt(i) - '0');
        List<Integer> C = add(A, B);
        for (int i = C.size() - 1; i >= 0; i--) System.out.printf(C.get(i) + "");
    }

    private static List<Integer> add(List<Integer> A, List<Integer> B) {
        List<Integer>C=new ArrayList<>(Math.max(A.size(),B.size())+2);
        int t=0;
        for(int i=0;i<A.size() || i<B.size();i++){
            if(i<A.size())t+=A.get(i);
            if(i<B.size())t+=B.get(i);
            C.add(t%10);
            t/=10;
        }
        if(t!=0) C.add(t);
        return C;
    }
}

2. 高精度减法 ✔1.31

原题链接
在这里插入图片描述
二刷:

  1. 小减大 需要转换成 大-小
  2. 如果出现负数 (x+10)%10 t = 1不是-1
  3. t = a[i] - t; t = t - b[i]
a.subtract(b)
import java.io.*;
import java.math.BigInteger;

public class Main {

    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BigInteger a = new BigInteger(reader.readLine());
        BigInteger b = new BigInteger(reader.readLine());
        System.out.println(a.subtract(b));
        reader.close();
    }
}
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.next();
        String s2 = scanner.next();
        List<Integer> A = new ArrayList<>();
        List<Integer> B = new ArrayList<>();
        for(int i = s1.length() - 1;i >= 0;i --) A.add(s1.charAt(i) - '0');
        for(int i = s2.length() - 1;i  >= 0; i --) B.add(s2.charAt(i) - '0');
        if(!cmp(A,B)){
            System.out.print("-");
        }
        List<Integer> C = sub(A,B);
        for(int i = C.size() - 1;i >= 0; i --){
            System.out.print(C.get(i));
        }


    }
    public static List<Integer> sub(List<Integer> A,List<Integer> B){
        if(!cmp(A,B)){
            return sub(B,A);
        }

        List<Integer> C = new ArrayList<>();
        int t = 0;
        for(int i = 0;i < A.size();i ++){
            //这里应该是A.get(i) - B.get(i) - t ,因为可能B为零,所以需要判断一下是不是存在
            t = A.get(i) - t;
            if(i < B.size()) t -= B.get(i);
            C.add((t + 10) % 10);

            if(t < 0) t = 1;
            else t = 0;
        }
        //删除指定下标下面的值
        while(C.size() > 1 && C.get(C.size() - 1) == 0)  C.remove(C.size() - 1);

        return C;
    }
    public static boolean cmp(List<Integer> A,List<Integer> B){
        if(A.size() != B.size()) return A.size() > B.size();
       /* if(A.size() >= B.size()){
            return true;
        }else{
            return false;
        }
        */
        for(int i = A.size() - 1;i >= 0;i --){
            if(A.get(i) != B.get(i)) {
                return A.get(i) > B.get(i);
            }
        }
        return true;
    }
}

3. 高精度乘法

二刷:

  1. 在草稿纸上演算一遍 运算过程,便知道 代码逻辑
    原题链接
    在这里插入图片描述
import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        String a = scanner.next();
        int b = scanner.nextInt();
        List<Integer> A = new ArrayList<>(a.length());
        for (int i = a.length()-1; i >= 0; i--) A.add(a.charAt(i) - '0');
        List<Integer> C = mul(A,b);
        for (int i = C.size()-1; i >= 0; i--) System.out.print(C.get(i));
    }
    
    public static List<Integer> mul (List<Integer> A,int b) {
        List<Integer> C = new ArrayList<>(A.size());
        int t = 0;
        for (int i = 0; i < A.size(); i++) {
            t = t + A.get(i)*b;
            C.add(t%10);
            t /= 10;
        }
        while (t != 0) {
            C.add(t%10);
            t /= 10;
        }
        while (C.size() > 1 && C.get(C.size()-1) == 0) {
            C.remove(C.size() - 1);
        }
        return C;
    }
}

4. 高精度除法 ✔(12分钟)2.1

原题链接

在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> div(vector<int> &A, int b, int &r)
{
    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

int main()
{
    string a;
    vector<int> A;

    int B;
    cin >> a >> B;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');

    int r;
    auto C = div(A, B, r);

    for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];

    cout << endl << r << endl;

    return 0;
}

五、前缀和S与差分a

1. 前缀和(2分钟)

原题链接

在这里插入图片描述

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] a = new int[n+1];
        int[] s = new int[n+1];
        for (int i = 1; i <= n; i++) { a[i] = scanner.nextInt(); }
        s[1] = a[1];
        for (int i = 2; i <= n; i++) {
            s[i] = a[i] + s[i-1];
        }
        while (m-- != 0) {
            int l = scanner.nextInt();
            int r = scanner.nextInt();
            System.out.println(s[r]-s[l-1]);
        }
    }
}

2. 子矩阵的和(7分钟)

原题链接
在这里插入图片描述

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int q = scanner.nextInt();
        int[][] a = new int[n+1][m+1];
        int[][] s = new int[n+1][m+1];
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= m; j++) {
                a[i][j] = scanner.nextInt();
            } 
        }
        for(int i = 1 ; i <= n  ; i ++ ){
            for(int j = 1 ;j <= m ; j ++ ){
                s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j];
            }
        }
        while (q-->0) {
            int x1 = scanner.nextInt();
            int y1 = scanner.nextInt();
            int x2 = scanner.nextInt();
            int y2 = scanner.nextInt();
            System.out.println(s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]);
        }
    }
}

3. 差分(9分钟)

二刷总结
  1. 由差分求s时,是要有数据连续性的,前面的改变了,要保证对应后面的也跟着

原题链接

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] nums = new int[n+2];
        for (int i = 1; i <= n; i++) {
            nums[i] = scanner.nextInt();
        }
        for (int i = n; i >= 1; i--) {
            nums[i] = nums[i]-nums[i-1];
        }
        for (int i = 0; i < m; i++) {
            int l = scanner.nextInt();
            int r = scanner.nextInt();
            int c = scanner.nextInt();
            nums[l] += c;
            nums[r+1] -= c;
        }
        for (int i = 1; i <= n; i++) {
            nums[i] += nums[i-1];
            System.out.printf("%d ",nums[i]);
        }
    }
}

4. 差分矩阵(12分钟)

原题链接

import java.util.*;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int q = scanner.nextInt();
        int[][] splits = new int[n+2][m+2];
        int[][] sum = new int[n+2][m+2];
        for (int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                sum[i][j] = scanner.nextInt();
                splits[i][j] = sum[i][j] - sum[i-1][j] - sum[i][j-1] + sum[i-1][j-1];
            }
        }
        for (int i = 0; i < q; i++) {
            int x1 = scanner.nextInt();
            int y1 = scanner.nextInt();
            int x2 = scanner.nextInt();
            int y2 = scanner.nextInt();
            int c = scanner.nextInt();
            splits[x1][y1] += c;
            splits[x1][y2+1] -= c;
            splits[x2+1][y1] -= c;
            splits[x2+1][y2+1] += c;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                sum[i][j] = splits[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
                System.out.print(sum[i][j] + " ");
            }
            System.out.println();
        }
    }
}

六、双指针

★ 1. 最长连续不重复子序列(20分钟)

二刷总结(以空间换时间)

原题链接

import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] a = new int[100010];
        int[] s = new int[100010];
        for(int i = 0 ; i < n ; i ++ ){
            a[i] = scan.nextInt();
        }
        int res = 0;
        for(int i = 0 , j = 0 ;i < n ; i ++ ){
            //比如一开始S[2]是0;然后你的a[1] = 2;那么s[2] = 1;
            //然后如果a[2] = 2 ;那么第二次出现所以s[2] = 2;这样来证明是不是出现两次
            s[a[i]] ++ ;
            while(j < i && s[a[i]] > 1){
                //一开始j是跟i在同个位置,i在移动,j原地不动,只要上面出现两次,j开始移动
                //j移动到i的位置,下面的代码就是i走过的路,让s[i] 数组里面加1的位置全部减1,就变回0;所以就继续往下统计长度
                s[a[j]] -- ;
                j++;
            }
            //i-j+1是统计长度的公式;
            res = Math.max(res, i-j+1);
        }
        System.out.println(res);
    }
}

//这里填你的代码^^
//注意代码要放在两组三个点之间,才可以正确显示代码高亮哦~

2. 数组元素的目标和(7分钟)

原题链接

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int x = scanner.nextInt();
        int[] A = new int[n+1];
        int[] B = new int[m+1];
        for (int i = 0; i < n; i++) A[i] = scanner.nextInt();
        for (int i = 0; i < m; i++) B[i] = scanner.nextInt();
        for (int i = 0,j = m-1; i < n && j >= 0;) {
            if (A[i] + B[j] < x) {
                i++;
            } else if (A[i] + B[j] == x) {
                System.out.print(i + " " + j);
                break;
            } else {
                j--;
            }
        }
    }
}

3. 判断子序列(8分钟)

原题链接

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] a = new int[n+1];
        int[] b = new int[m+1];
        for (int i = 0; i < n; i++) a[i] = scanner.nextInt();
        for (int j = 0; j < m; j++) b[j] = scanner.nextInt();
        boolean flag = false;
        for (int i = 0,j = 0; j < m; j++) {
            if (a[i] == b[j]) {
                i++;
                if (i == n) {
                    System.out.print("Yes");
                    flag = true;
                    break;
                }
            }
        }
        if (flag == false) {
            System.out.print("No");
        }
    }
}

七、二进制

最全二进制算法总结

1. 位运算算法(2分钟)

返回n的最后一位1:lowbit(n) = n & -n
一共有多少1 : while n = n ^(n & -n)或者 n -= n & -n

原题链接

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
            System.out.print(numberOfOneInBinary(nums[i]) + " ");
        }
    }
    
    public static int numberOfOneInBinary(int num) {
        int cnt = 0;
        while (num != 0) {
            num -= (num & -num);
            cnt++;
        }
        return cnt;
    }
}

八、离散化

sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
去重 V.erase(unique(.begin(),.end()),.end());

1. ★ 区间和

原题链接

在草稿纸上列出需要几个数组,就清晰了
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        pair[] add = new pair[n+2];
        pair[] query = new pair[m];
        List<Integer> arrayMap = new ArrayList<>(n+m*2);
        int[] sum = new int[n+m*2];
        for (int i = 0; i < n; i++) {
            add[i] = new pair();
            add[i].l = scanner.nextInt();
            add[i].r = scanner.nextInt();
            arrayMap.add(add[i].l);
        }
        for (int i = 0; i < m; i++) {
            query[i] = new pair();
            query[i].l = scanner.nextInt();
            query[i].r = scanner.nextInt();
            arrayMap.add(query[i].l);
            arrayMap.add(query[i].r);
        }
        arrayMap = new ArrayList<>(new HashSet<>(arrayMap));
        Collections.sort(arrayMap);
        for (int i = 0; i < n; i++) {
            sum[arrayMapIndexOf(add[i].l,arrayMap)] += add[i].r;
        }
        for (int i = 0; i < arrayMap.size(); i++) {
            if(i != 0) {
                sum[i] += sum[i-1];
            }
        }
        for (int i = 0; i < query.length; i++) {
            int l = arrayMapIndexOf(query[i].l,arrayMap);
            int r = arrayMapIndexOf(query[i].r,arrayMap);
            if (l == 0) {
                System.out.print(sum[r] + "\n");
            } else {
                System.out.print(sum[r]-sum[l-1] + "\n");
            }
        }
    }
    
    static class pair {
        int l;
        int r;
    }
    
    private static int arrayMapIndexOf(int k,List<Integer> arrayMap) {
        int l = 0,r = arrayMap.size()-1;
        while (l < r) {
            int mid = (l+r+1) >> 1;
            if (arrayMap.get(mid) <= k) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }
        return r;
    }
}

九、区间合并

1. 区间合并(7分钟)

原题链接

贪心做法

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        pair[] range = new pair[n];
        for (int i = 0; i < n; i++) {
            range[i] = new pair();
            range[i].l = scanner.nextInt();
            range[i].r = scanner.nextInt();
        }
        Arrays.sort(range,new Comparator<pair>(){
          @Override
          public int compare(pair o1,pair o2) {
              if (o1.l == o2.l) {
                  return o1.r - o2.r;
              } else {
                  return o1.l - o2.l;
              }
          }
        });
        int st = (int)-2e9-1;
        int ed = (int)-2e9-1;
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            if (ed < range[i].l) {
                st = range[i].l;
                ed = range[i].r;
                cnt++;
            } else {
                ed = Math.max(ed,range[i].r);
            }
        }
        System.out.print(cnt);
    }
    
    static class pair {
        int l;
        int r;
    }
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【操作系统】聊聊Linux内存工作机制

内存主要是用来存储系统和应用程序的指令、数据、缓存等 内存映射 内存是需要安全机制保护的&#xff0c;所以只有内核才可以直接访问物理内存。进程如果要访问内存需要通过独立的虚拟地址空间。 虚拟地址空间其实包含两部分。一部分是内核空间&#xff0c;另一部分就是用户…

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…

【AI】机器学习——线性模型(线性回归)

线性模型既能体现出重要的基本思想&#xff0c;又能构造出功能更加强大的非线性模型 文章目录 3.1 线性模型3.1.1 数据3.1.2 目标/应用 3.2 线性回归3.2.1 回归模型历史3.2.2 回归分析研究内容回归分析步骤 3.2.3 回归分析分类3.2.4 回归模型3.2.5 损失函数梯度下降法一元回归模…

【数据仓库基础(二)】数据仓库架构

文章目录 一. 基本架构二. 主要数据仓库架构1. 数据集市架构1.1. 独立数据集市1.2. 从属数据集市1.3. Inmon企业信息工厂架构 2. Kimball数据仓库架构3. 混合型数据仓库架构 三. 操作数据存储&#xff08;ODS&#xff09; 一. 基本架构 架构是指系统的一个或多个结构。结构中包…

stride与padding对输出尺寸的计算

公式&#xff1a; 练习&#xff1a; 图1&#xff1a; input4&#xff0c;filter3&#xff0c;padding0&#xff0c;stride1 output2 图2&#xff1a; input5&#xff0c;filter3&#xff0c;padding0&#xff0c;stride2 output2 图3&#xff1a; input6&#xff0c;filter3&am…

设计模式之观察者模式、访问者模式与模板方法模式

目录 观察者模式 简介 优缺点 结构 实现 运用场景 访问者模式 简介 优缺点 结构 实现 运用场景 模板方法模式 简介 优缺点 结构 实现 运用场景 观察者模式 简介 又叫发布-订阅模式&#xff0c;定义对象间一种一对多的依赖关系&#xff0c;使得每当一个对象改…

Android 应用程序通过MediaPipe 图片识别

MediaPipe 中使用目标检测模型可以实现实时检测图像或视频中的物体&#xff0c;并标记出物体的位置和类别。MediaPipe 中的目标检测模型基于机器学习算法&#xff0c;经过训练以识别特定的物体类别&#xff1b; 以下是在 Android 应用程序中集成 MediaPipe Object Detection 的…

SpringMVC应用

文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…

Nacos启动连接mysql报错

问题 Nacos启动后&#xff0c;访问http://localhost:8848/nacos/index.html一直访问不了&#xff0c;查看nacos安装目录下的logs/config-fatal.log日志文件发现连接mysql报错&#xff0c;但是通过客户端连接工具测试mysql连接正常&#xff1b;核心报错如下&#xff1a; Cause…

【线程池】面试被问到线程池参数如何配置时该如何回答

前言 没有基于业务场景&#xff0c;直接抛出这个问题&#xff0c;等同于耍流氓。 八股文告诉我们CPU密集型就核心数1&#xff0c;IO密集型就核心数*2&#xff0c;那么真实业务中该怎么去配置呢。 方法论还是有的 1.需要分析线程池执行的任务的特性&#xff1a; CPU 密集型还是 …

【操作】安防监控/视频汇聚/视频云存储EasyCVR平台AI智能分析网关V3接入教程2.0

TSINGSEE的边缘计算硬件智能分析网关V3内置多种AI算法模型&#xff0c;包括人脸、人体、车辆、车牌、行为分析、烟火、入侵、聚集、安全帽、反光衣等等&#xff0c;可应用在安全生产、通用园区、智慧食安、智慧城管、智慧煤矿等场景中。将网关硬件结合TSINGSEE青犀的视频汇聚/安…

数据结构-01 数据结构基本概念,算法时间复杂度,空间复杂度

0 数据结构概述 四门课的关系 1 绪论 数据对象、数据元素、数据项关系 1.1 数据结构的基本概念 1.2 算法和算法评价 小练习 空间复杂度中的递归调用 n只是传入 n也是数组&#xff0c;计算存储数组flag的空间大小

HTTPS协议和SOCKS5协议的区别

HTTPS协议和SOCKS5协议是两种不同的网络协议&#xff0c;它们在传输数据的方式、安全性和使用场景等方面都有所不同。下面将介绍HTTPS协议与SOCKS5协议的区别。 传输数据的方式 HTTPS协议是一种基于HTTP协议的安全协议&#xff0c;它使用SSL/TLS协议对数据进行加密和解密。在传…

Kafka3.0.0版本——消费者(独立消费者消费某一个主题数据案例__订阅主题)

目录 一、独立消费者消费某一个主题数据案例1.1、案例需求1.2、案例代码1.3、测试 一、独立消费者消费某一个主题数据案例 1.1、案例需求 创建一个独立消费者&#xff0c;消费firstTopic主题中数据&#xff0c;所下图所示&#xff1a; 注意&#xff1a;在消费者 API 代码中必…

时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测(风电功率预测)

时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测&#xff08;风电功率预测&#xff09; 目录 时序预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测&#xff08;风电功率预测&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1…

Matlab 如何把频谱图的纵坐标设置为分贝刻度

Matlab 如何把频谱图的纵坐标设置为分贝刻度 Matlab代码如下&#xff1a; % 如何把频谱图的纵坐标设置为分贝刻度 % % pr2_2_6 clc; clear; close all;load pr2_2_6_sndata1.mat % 读入数据 X fft(y); % FFT n2 1:L/21; % 计算正频率…

天翼云不做备案接入,如何绑定域名,不用80端口,443端口。

443&#xff0c;80端口不开启。 第一步&#xff1a; 宝塔更改web端口 搞个复杂的端口。 第二步&#xff1a; 在天翼云策略组上面开启修改过的web端口。 第三步&#xff1a;接入cdn&#xff0c;端口改成修改过的端口。

EVA: Visual Representation Fantasies from BAAI

本文做个简单总结&#xff0c;博主不是做自监督领域的&#xff0c;如果错误&#xff0c;欢迎指正。 链接 Code&#xff1a; Official&#xff1a;baaivision/EVA MMpretrain&#xff1a;open-mmlab/mmpretrain/tree/main/configs/eva02 Paper&#xff1a; EVA01&#xff1a;…

LAMP搭建WordPress

L linux A apache hhtpd M mysql/maridb P PHP1、 安装php yum -y install php php-fpm php-server php-mysql1.1、 启动php-fpm并自启 systemctl enable php-fpm --now[rootecs-1cee ~]# systemctl status php-fpm ● php-fpm.service - The PHP FastCGI Process ManagerLoa…

Ae 效果:CC Cross Blur

模糊和锐化/CC Cross Blur Blur & Sharpen/CC Cross Blur CC Cross Blur&#xff08;CC 交叉模糊&#xff09;可以通过单独控制水平和垂直方向的模糊程度来创建独特的交叉模糊效果&#xff0c;可以产生类似光线交错的视觉外观。 ◆ ◆ ◆ 效果属性说明 Radius X 半径 X 用…