ACWing算法基础课||第一讲||基础算法记录(完结撒花~)

导入

都是模板题,理解 + 背过就行

【快排】AcWing 785.快速排序

题目链接:acwing快速排序

题目

在这里插入图片描述

快排思路解释

第一步:确定分界点(假设值为x):arr[l],arr[r],arr[(l+r) /2],arr[随机下标]理论上都可以,但是注意边界处理。

⭐第二步:调整区间:所有<=x的在左半边,所有>=x的在右半边。

第三步:递归处理左右两端。

代码展示

输入比较大,比较多,java使用Bufferreader。

快排属于分治算法,分治算法都有三步:
1,分成子问题
2,递归处理子问题
3,子问题合并(快排这一步不需要操作,但归并排序的核心在这一步骤)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
    static int N = 100010;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());
        int arr[] = new int[N];
        //Bufferreader输入是字符串数组,所以要把字符串再用Integer.parseInt()转化。
        String strs[] = reader.readLine().split(" ");
        for(int i = 0;i < n;i++){
            arr[i] = Integer.parseInt(strs[i]);
        }
        quickSort(arr,0,n - 1);
        for(int i = 0;i < n;i++){
            System.out.print(arr[i] + " ");
        }
    }
    public static void quickSort(int arr[],int l,int r){
        if(l >= r) return;//递归终止条件
        int mid = arr[(l + r) / 2];//随机一个数组里面的值
        //1,分成子问题
        int p1 = l-1;
        int p2 = r+1;
        while(p1 < p2){
            do{p1++;} while(arr[p1] < mid);
            do{p2--;} while(arr[p2] > mid);
            if(p1 < p2){
                int temp = arr[p1];
                arr[p1] = arr[p2];
                arr[p2] = temp;
            }
        }
        //2,递归处理子问题
        quickSort(arr,l,p2);
        quickSort(arr,p2+1,r);
    }
}

递归处理子问题解释为什么是终止到p2

递归处理子问题中: quickSort(arr,l,p2)-------------quickSort(arr,p2+1,r);
为什么不能用--------quickSort(arr,l,p1)-------------quickSort(arr,p1+1,r);
⭐误区:终止时,l和r不一定相等,可能r比l提前一位(例:3 5 4 1 2 2 4 5,第一次终止时,p1在下标为1,p2在下标为0位置)
⭐解释:a[i] 是一定大于等于 x 的,你把a[i]划到左边,可能使左边序列存在大于 x 的元素,并不能保证左边元素均小于等于 x。

【快排】AcWing 786. 第k个数

题目链接 AcWing 786. 第k个数

题目

在这里插入图片描述

代码展示

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int arr[] = new int[100010];
        for(int i = 0;i < n;i++) arr[i] = sc.nextInt();
        System.out.println(quickSort(arr,0,n - 1,k));
    }
    public static int quickSort(int arr[],int l,int r,int k){
        if(l >= r) return arr[l];//因为是函数是返回int类型,所以要返回arr[l]或arr[r]
        int mid = arr[(l + r) / 2];
        int p1 = l - 1;
        int p2 = r + 1;
        while(p1 < p2){
            do{p1++;}while(arr[p1] < mid);
            do{p2--;}while(arr[p2] > mid);
            if(p1 < p2){
               int t = arr[p1];
               arr[p1] = arr[p2];
               arr[p2] = t;
            }
        }
        //sl——左半部分长度
        int sl = p2 - l + 1;
        //判断k在左半部分还是右半部分,再递归
        if(k <= sl){
            return quickSort(arr,l,p2,k);
        }
        return quickSort(arr,p2 + 1,r,k - sl);
    }
}

【归并】AcWing 787. 归并排序

题目链接:787. 归并排序

题目

在这里插入图片描述

代码思路

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, tmp[r - l + 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(int i = 0;i < temp.length;i++)  arr[l++] = temp[i]; 

代码展示

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());
        String strs[] = reader.readLine().split(" ");
        int arr[] = new int[100010];
        for(int i = 0;i < n;i++){
            arr[i] = Integer.parseInt(strs[i]);
        }
        mergeSort(arr,0,n - 1);
        for(int i = 0;i < n;i++){
            System.out.print(arr[i] + " ");
        }
    }
    public static void mergeSort(int arr[],int l,int r){
        if(l >= r) return;
        int mid = (l + r) / 2;
        mergeSort(arr,l,mid);
        mergeSort(arr,mid + 1,r);
        int p1 = l,p2 = mid + 1,k = 0;
        int temp[] = new int [r - l + 1];
        while(p1 <= mid && p2 <= r){
            if(arr[p1] <= arr[p2]){
                temp[k++] = arr[p1++];
            }
            else{
                temp[k++] = arr[p2++];
            }
        }
        while(p1 <= mid) temp[k++] = arr[p1++];
        while(p2 <= r) temp[k++] = arr[p2++];
        for(int i = 0;i < temp.length;i++){
            arr[l++] = temp[i];
        }
    }
}

【二分】AcWing 789. 数的范围

题目链接:789. 数的范围

题目

在这里插入图片描述

关于代码

⭐记得二分的mid也是从中间分开,mid = l + (r - l) / 2

代码展示

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String nums[] = reader.readLine().split(" ");
        int n = Integer.parseInt(nums[0]);
        int q = Integer.parseInt(nums[1]);
        String str[] = reader.readLine().split(" ");
        int arr[] = new int[n];
        for (int i = 0; i < n; i++) arr[i] = Integer.parseInt(str[i]);
        while (q-- > 0) {
            int x = Integer.parseInt(reader.readLine());
            System.out.println(left(arr, x) + " " + right(arr, x));
        }
    }
   
    public static int left(int arr[],int x){
        int l = 0,r = arr.length - 1;
        while(l <= r){
            int mid = l + (r - l) / 2;
            if(arr[mid] > x) r = mid - 1;
            else if(arr[mid] < x) l=  mid + 1;
            else r = mid - 1;
        }
        if(l >= 0 && l < arr.length && arr[l] == x) return l;
        return -1;
    }
    
    public static int right(int arr[],int x){
        int l = 0,r = arr.length - 1;
        while(l <= r){
            int mid = l + (r - l) / 2;
            if(arr[mid] > x)  r = mid - 1;
            else if(arr[mid] < x) l = mid + 1;
            else l = mid + 1;
        }
        if(r >= 0 && r < arr.length && arr[r] == x) return r;
        return  -1;
    }
}

【二分】AcWing 790. 数的三次方根

题目链接:AcWing 790. 数的三次方根

题目

在这里插入图片描述

代码展示

import  java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        double x = sc.nextDouble();
        double l = -10000,r = 10000;
        //经验:精度比所求精度高 2位
        while((r - l) > 1e-8){
            double mid = (l + r) / 2;
            if(mid * mid * mid >= x){
                r = mid;
            }
            else l = mid;
        }
        //输出l和r都可以。因为r - l <= 1e-8,即r和l保留小数点后六位的话俩数字一样
        System.out.printf("%.6f",l);
    }
}

【前缀和】AcWing 795. 前缀和

题目链接:AcWing 795. 前缀和

题目

在这里插入图片描述

代码展示

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int a[] = new int[100010];
        int s[] = new int[100010];
        for(int i = 1;i <= n;i++){
            a[i] = sc.nextInt();
            s[i] = s[i - 1] + a[i];
        }
        while(k-->0){
            int l = sc.nextInt();
            int r = sc.nextInt();
            System.out.println(s[r] - s[l - 1]);
        }
    } 
}

【差分】AcWing 797. 差分

题目链接:AcWing 797. 差分

题目

在这里插入图片描述

代码展示

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 s[] = new int[100010];
        int a[] = new int[100010];
        for(int i = 1;i <= n;i++){
            s[i] = sc.nextInt();
            a[i] = s[i] - s[i - 1];
        }
        while(m-->0){
            int l = sc.nextInt();
            int r = sc.nextInt();
            int c = sc.nextInt();
            a[l] += c;
            a[r + 1] -= c;
        }
        for(int i = 1;i <= n;i++){
            s[i] = s[i - 1] + a[i];
            System.out.print(s[i] + " ");
        }
    }
}

【双指针】AcWing 799. 最长连续不重复子序列

题目链接:AcWing 799. 最长连续不重复子序列

题目

在这里插入图片描述

代码展示

import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int arr[] = new int[n + 10];
        for(int i = 0;i < n;i++){
            arr[i] = sc.nextInt();
        }
        
        int res = 1;//不重复长度
        int i = 0;//慢指针
        Map<Integer,Integer> map = new HashMap<>();//记录出现次数
        for(int j = 0;j < n;j++){
            map.put(arr[j],map.getOrDefault(arr[j],0) + 1);//记录出现次数
            while(map.get(arr[j]) > 1){//次数 > 1,删除记忆
                map.put(arr[i],map.get(arr[i]) - 1);
                i++;
            }
            res = Math.max(res,j - i + 1);
        }
        System.out.println(res);
    }
}

【双指针】AcWing 800. 数组元素的目标和

题目链接:AcWing 800. 数组元素的目标和

题目

在这里插入图片描述

代码展示

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 x = sc.nextInt();
        int arr[] = new int[100010];
        int brr[] = new int[100010];
        for(int i = 0;i < n;i++){
            arr[i] = sc.nextInt();
        }
        for(int i = 0;i < m;i++){
            brr[i] = sc.nextInt();
        }
        int l = 0,r = m - 1;
        while(l < n && r >= 0){
            if(arr[l] + brr[r] > x){
                r--;
            }
            else if(arr[l] + brr[r] < x){
                l++;
            }
            else{
                System.out.print(l + " " + r);
                break;
            }
        }
    }
}

【双指针】AcWing 2816. 判断子序列

题目链接:AcWing 2816.判断子序列

题目

在这里插入图片描述

代码展示

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 a[] = new int[100010];
        int b[] = new int[100010];
        for(int i = 0;i < n;i++) a[i] = sc.nextInt();
        for(int i = 0;i < m;i++) b[i] = sc.nextInt();
        int i = 0;
        for(int j = 0;j < m;j++){
            if(i < n && a[i] == b[j]) i++;
            if(i == n) break;
        }
        if(i == n){
            System.out.println("Yes");
        }else{
            System.out.println("No");
        }
    }
}

【位运算】AcWing 801. 二进制中1的个数

题目链接:AcWing 801.二进制中1的个数

题目

在这里插入图片描述

代码展示

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int arr[] = new int[n];
        for(int i = 0;i < n;i++){
            arr[i] = sc.nextInt();
        }
        
        for(int i = 0;i < n;i++){
            int count = 0;
            int x = arr[i];
            //核心代码
            while(x != 0){
                x -= lowbit(x);
                count++;
            }
            System.out.print(count+" ");
        }
    }
    //得到x二进制表示中最右边的1所对应的数值
    public static int lowbit(int x){
        return x & (-x);
    }
}

【区间合并】AcWing 803. 区间合并

题目链接:AcWing 803.区间合并

题目

在这里插入图片描述

代码展示

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //用来放数组的集合list
        ArrayList<int []> list = new ArrayList();
        //把输入的区间都先放到集合里面
        for(int i = 0;i < n;i++){
            int a[] = new int[2];
            a[0] = sc.nextInt();
            a[1] = sc.nextInt();
            list.add(a);
        }
        
        //对集合里面的数组,按照区间左端点进行排序
        list.sort(new Comparator<int[]>(){
            @Override
            public int compare(int[] o1,int[] o2){
                return o1[0] - o2[0];
            }
        });
        
        //扫描整个区间,扫描过程中,把所有有交集的区间进行合并。
        //具体做法:每次维护一个“当前区间”,扫描到第i个区间时候,判断与“当前区间”关系:
        //情况1,第i个区间和“当前区间”有交集(含被包含情况),更新r(r =  Math.max(r,a[1]));
        //情况2,第i个区间和“当前区间”没有交集,k++就行,自动再是为第i个区间为“当前区间”
        int k = 0;
        int r = Integer.MIN_VALUE;
        for(int a[] : list){
            if(a[0] > r){
                k++;
            }
            r = Math.max(r,a[1]);
        }
        System.out.println(k);
    }
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: acwing算法基础课是一门针对算法学习的在线课程,在这门课程中,学生可以系统地学习和掌握算法基础知识,提高编程水平。为了方便学生学习,acwing提供了网盘服务。 acwing算法基础课网盘是一个用于存储课程资源的平台。通过这个网盘,学生可以下载课程义、代码模板以及补充材料等。这些资源都经过精心整理,供学生们参考和学习。 网盘中的资源是按照课程章节进行分类的,学生可以根据自己的学习需要,选择性地下载所需的资料。同时,网盘还提供了搜索功能,方便学生快速定位和获取所需资料。 acwing算法基础课网盘的使用对于学生们的学习非常有帮助。通过下载和学习这些资源,学生们可以更好地理解课程内容,加深对算法的理解。此外,学生们还可以通过研究代码模板,学习优秀的编程思想和技巧,提高自己的编程能力。 总之,acwing算法基础课网盘是一项非常便利和实用的服务,为学生们提供了更加全面和深入的学习资源,帮助他们更好地掌握和运用算法知识。 ### 回答2: acwing算法基础课是一门优质的算法学习资源,其中的课程内容丰富多样,涵盖了算法基础知识、数据结构、动态规划、图论等等。很多学习者都认为这门课程对他们的算法学习有很大的帮助。 网盘是指以网络为媒介,提供文件存储和下载服务的云存储平台。acwing算法基础课也提供了网盘服务,方便学习者下载课程资料并进行学习。 通过acwing算法基础课网盘,学习者可以方便地获取到课程的各种学习资料,包括义、习题集、代码示例等。这些资料可以帮助学习者更好地理解和掌握课程的内容。此外,网盘还提供了上传和分享功能,学习者可以将自己的学习心得、代码等资料分享给其他学习者,促进学习者之间的互相学习和交流。 acwing算法基础课网盘的优点不仅仅是方便快捷的下载和分享功能,还包括安全可靠的存储环境。学习者可以放心地将自己的学习资料上传到网盘进行备份,减少数据丢失的风险。同时,网盘还提供了多种存储空间容量的选择,满足学习者不同的需求。 总的来说,acwing算法基础课网盘为学习者提供了方便、安全和多样化的学习资源下载和分享服务,为学习者的算法学习和进步提供了有力的支持。如果你对算法感兴趣,我推荐你去尝试一下这门精彩的课程!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘忆柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值