AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表

这篇具有很好参考价值的文章主要介绍了AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单链表.

链表题目:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing. 826.单链表

import java.util.Scanner;
public class Main{
        static int[] e = new int[100010];//结点i的值
        static int[] ne = new int[100010];//结点i的next指针
        static int idx,head;//head是头结点,idx存当前已经用到了哪个点
        public static void init(){
            idx = 0;
            head = -1;
        }
    //H向链表头插入一个数x;
    public static void add_head(int x){
        e[idx] = x;
        ne[idx] = head;
        head = idx++;
    } 
    //I在第k位数后面插入一个数x
    public static void add(int k,int x){
        e[idx] = x;
        ne[idx] = ne[k];
        ne[k] = idx++;
    }
    //D删除第k个数后面得数
    public static void remove(int k){
        ne[k] = ne[ne[k]];
    }
    public static void main(String[] args){
         Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();

        init();
        while(m -- > 0){
            //因为java中没有输入一个字符,所以用字符串转字符
            String s = scan.next();
            char op = s.charAt(0);

            if(op == 'H'){
                int x = scan.nextInt();
                add_head(x);
            }else if(op == 'D'){
                int k = scan.nextInt();
                if(k == 0) head = ne[head];
                else remove(k-1);
            }else {
                int k = scan.nextInt();
                int x = scan.nextInt();
                add(k-1,x);
            }
        }
        for(int i = head;i != -1;i = ne[i] ){
            System.out.print(e[i] +  " ");
        }
    }
}

双链表

AcWing 827.双链表

import java.util.Scanner;
public class Main{
    static int N = 100010;
    static int[] e = new int[N];//元素
    static int[] r = new int[N];//右指针
    static int[] l = new int[N];//左指针
    static int idx;

    //删除第k位插入的数
    public static void remove(int k){
        r[l[k]] = r[k];
        l[r[k]] = l[k];
    }
    //这是在第k位数后面插入一个数x
    public static void add_all(int k,int x){
        e[idx] = x;
        r[idx] = r[k];
        l[idx] = k;
        l[r[k]] = idx;
        r[k] = idx++;
    }
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();

        r[0] = 1;l[1] = 0;idx = 2;

        while(m -- > 0){
            String s = scan.next();
            char op = s.charAt(0);
            if(op == 'L'){
                int x = scan.nextInt();
                add_all(0,x);
            }else if(op == 'R'){
                int x = scan.nextInt();
                add_all(l[1],x);
            }else if(op == 'D'){
                int k = scan.nextInt();
                remove(k + 1);
            }else if(s.equals("IR")){
                int k  = scan.nextInt();
                int x = scan.nextInt();
                add_all(k + 1,x);
            }else {
                int k = scan.nextInt();
                int x = scan.nextInt();
                add_all(l[k+1],x);
            }
        }
       for(int i = r[0];i != 1; i= r[i]){
            System.out.print(e[i]  + " ");
        }
    }
}

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 828.模拟栈

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();
        int[] stl = new int[100010];
        int tt = 0;

        while(m -- > 0){
            String s = scan.next();

            if(s.equals("push")){
                int x= scan.nextInt();
                stl[++tt] = x;
            }else if(s.equals("pop")){
                tt--;
            }else if(s.equals("empty")){
                if(tt > 0){
                    System.out.println("NO");
                }else System.out.println("YES");
            }else{
                System.out.println(stl[tt]);
            }

        }
    }
}

AcWing 3302.表达式求值

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        //以字符串形式输入表达式
        String s = scan.next();
        //map来添加运算符号进去,定义优先级
        Map<Character,Integer> map = new HashMap<>();
        map.put('+',1);
        map.put('-',1);
        map.put('*',2);
        map.put('/',2);

        Stack<Character> op = new Stack<>();//存运算符号
        Stack<Integer> num = new Stack<>();//存数字

        for(int i = 0 ; i < s.length(); i ++ ){
            char c = s.charAt(i);
            //判断c字符是不是数字
            if(Character.isDigit(c)){
                int x = 0,j = i;
                //数字可能会是多位数,
                while(j < s.length() && Character.isDigit(s.charAt(j))){
                    x = x * 10 + s.charAt(j) - '0';
                    j++;
                }
                num.push(x);//将数字x存入数字栈栈顶
                i = j - 1;//重新赋值i
            }else if(c == '('){
                op.push(c); // 将左括号存入字符栈栈顶
            }else if(c == ')'){
                //如果栈顶不等于左括号,一直计算下去;
                while(op.peek() != '('){
                    eval(op,num);
                }
                op.pop(); // 将左括号弹出栈顶
            }else { //如果是正常字符
                while(!op.empty() && op.peek() != '(' && map.get(op.peek()) >= map.get(c)){
                    eval(op,num);
                }
                op.push(c);
            }
        }
        while(!op.empty()) eval(op,num);
        System.out.println(num.peek());
    }
    public static void eval(Stack<Character> op,Stack<Integer> num){
        int b = num.pop();
        int a = num.pop();

        char c = op.pop();
        if(c == '+'){
           num.push(a+b);
        }else if(c == '-'){
            num.push(a-b);
        }else if(c == '*'){
            num.push(a*b);
        }else {
            num.push(a/b);
        }
    }
}

队列

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 829. 模拟队列

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();
        //队列是在tt队尾插入元素,队头hh弹出元素
        int[] dl = new int[100010];
        int hh = 0;
        int tt = -1;
        while(m -- > 0){
            String s = scan.next();
            if(s.equals("push")){
                int x = scan.nextInt();
                dl[++tt] =  x;
            }else if(s.equals("pop")){
                hh++;
            }else if(s.equals("empty")){
                if(hh <= tt) System.out.println("NO");
                else System.out.println("YES");
            }else {
                System.out.println(dl[hh]);
            }
        }
    }
}

单调栈

AcWing 830.单调栈

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] stk  = new int[100010];
        int tt = 0;

        for(int i = 0 ; i < n ;  i++ ){
            int x = scan.nextInt();
            //如果栈非空 ,栈顶元素>= x,那么说明栈顶这个数不满足需求,
            //因为比较的是左边第一个最近最小的数,所以就把stk[tt]弹出了;
            while(tt!=0 && stk[tt] >= x){
                tt--;
            }
            //如果弹出操作完了之后,栈不是空的,就输出栈顶元素,
            if(tt != 0) System.out.print(stk[tt]+" ");
            //否则就是栈是空的,输出-1
            else System.out.print("-1" + " ");
            //最后将x插入栈顶;
            stk[++tt] = x;
        }
    }
}

单调队列

AcWing 154.滑动窗口

import java.io.*;
public class Main{
    static int N = 1000010;
    static int n,k;//数组长度 和 滑动窗口长度
    static int hh,tt;//队头队尾
    static int[] q = new int[N];//q是队列 存的是 下标
    static int[] a = new int[N];
    public static void main(String[] args)throws IOException{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wt = new PrintWriter(new OutputStreamWriter(System.out));
        String[] st = bf.readLine().split(" ");
        n = Integer.parseInt(st[0]);
        k = Integer.parseInt(st[1]);
        String[] str = bf.readLine().split(" ");
        for(int i = 0 ; i < n ; i ++ ) a[i] = Integer.parseInt(str[i]);

        hh = 0;tt = - 1;//队头队尾 感觉像双指针
        for(int i = 0 ; i < n ; i ++ ){//i是 滑动窗口的 终点
            //队列非空 hh <= tt且 队头在起点之前 就出栈
            if(hh <= tt && q[hh] < i - k + 1) hh ++;//起点:i-k+1
            //这个while 就是 控制 这个队列的单调性递增!
            //非空 & 队尾元素 >= 新加进来的元素,就将队尾删掉,因 队头存的是窗口中最小的
            while(hh <= tt && a[q[tt]] >= a[i]) tt --;  //求最小值所以保留最小值
            q[++ tt] = i;//当前 位置插到 队尾
            //不足k 不用判断 
            if(i >= k - 1) wt.print(a[q[hh]] + " ");
        }
        wt.println();
        hh = 0;tt = -1;
        for(int i = 0 ; i < n ; i ++){
            if(hh <= tt && q[hh] < i - k + 1) hh ++;
            while(hh <= tt && a[q[tt]] <= a[i]) tt --;//求最大值所以保留最大值

            q[++ tt] = i;
            if(i >= k - 1) wt.print(a[q[hh]] + " ");
        }
        wt.flush();//记得刷新流
    }
}

KMP

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 831. KMP字符串

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class Main{
    static int N = 100010;
    static int ne[] = new int[N];//kmp核心数组next[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        Integer n = Integer.parseInt(br.readLine());//输入p字符的长度
        String s1 = " " + br.readLine();//输入p字符串
        Integer m = Integer.parseInt(br.readLine());
        String s2 = " " + br.readLine();
        char[] a1 = s1.toCharArray();//创建p数组 存字符
        char[] a2 = s2.toCharArray();
        /**
         * ne[]:存储一个字符串以每个位置为结尾的‘可匹配最长前后缀’的长度。
         * next[i]=j 等价 p[1,j]=p[i-j+1,i]
         * 构建ne[]数组:
         *              1,初始化ne[1] = 0,i从2开始。当第一个数时就是0所以不用参与。默认是0;
         *              2,若匹配,s[i]=s[j+1]说明1~j+1是i的可匹配最长后缀,ne[i] = ++j;
         *              3,若不匹配,则从j的最长前缀位置+1的位置继续与i比较
         *              (因为i-1和j拥有相同的最长前后缀,我们拿j的前缀去对齐i-1的后缀),
         *              即令j = ne[j],继续比较j+1与i,若匹配转->>2
         *              4,若一直得不到匹配j最终会降到0,也就是i的‘可匹配最长前后缀’的长度
         *              要从零开始重新计算
         */
        for(int i = 2,j = 0;i <= n ;i++) {
            //这里判断从j是不是>=0,如果< 0,表示还没有前缀和后缀相等
            while(j!=0&&a1[i]!=a1[j+1]) j = ne[j]; //不相等就让j等于上一个数的next[];
            if(a1[i]==a1[j+1]) j++;//匹配 有一个相等,前缀和后缀相等长度为1.
            ne[i] = j;
        }
        /**
         * 匹配两个字符串:
         *      1,从i=1的位置开始逐个匹配,利用ne[]数组减少比较次数
         *      2,若i与j+1的位置不匹配(已知1~j匹配i-j~i-1),
         *      j跳回ne[j]继续比较(因为1~j匹配i-j~i-1,所以1~ne[j]也能匹配到i-ne[j]~i-1)
         *      3,若匹配则j++,直到j==n能确定匹配成功
         *      4,成功后依然j = ne[j],就是把这次成功当成失败,继续匹配下一个位置
         */
        for(int i = 1,j = 0; i <= m;i++) {
            while(j!=0&&a2[i]!=a1[j+1]) j = ne[j];
            if(a2[i]==a1[j+1]) j++;
            if(j==n) {//相等的数= 短的数组的长度,就说明该输出了
                j = ne[j];//输出之后,要继续往下面遍历对比,所以让j=上一个数的缀长度,
                bw.write(i-n+" ");
            }
        }
        /**
         * 时间复杂度:
         *      因为:j最多加m次,再加之前j每次都会减少且最少减一,j>0
         *      所以:while循环最多执行m次,若大于m次,j<0矛盾
         *      最终答案:O(2m)
         */
        //所有write下的内容,会先存在writers中,当启用flush以后,会输出存在其中的内容。
        //如果没有调用flush,则不会将writer中的内容进行输出。
        bw.flush();
    }
}

Trie:高效地存储和查找字符串集合的数据结构

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 835. Trie字符串统计

import java.util.Scanner;
public class Main{
    static int N = 100010,idx = 0;//idx是当前用到的下标
    static int[][] song = new int[N][26];//每个点的儿子集合最多26个字母儿子
    static int[] cnt  = new int[N];//存当前结尾的单词有多少个
    static char[] str = new char[N];
    //插入字符串
    public static  void insert(char[] str){
        int p = 0; //下标0表示头结点,根节点
        for(int i = 0 ; i < str.length; i ++ ){
            // 将字符串每个字符a-z 映射成数字;0-25
            int u = str[i] - 'a'; 
            //如果这个儿子分支没有字符,说明这条分支还没有这个字符插入过
            //就创建出来 把【idx】下标赋值上去,作为每个分支的专属坐标
            if(song[p][u] == 0) song[p][u] = ++idx;
            //然后将p往下前进一层
            p = song[p][u];
        }
        //最后停在那一层的那个数字就做标记,说明这是要找的字符串的结尾
        cnt[p]++;
    }
    public static int query(char[] str){
        int p = 0;//从根节点开始,下标是0表示根节点,头结点
        for(int i = 0 ; i < str.length; i ++){
            int u = str[i] - 'a'; // 将字符串每个字符都转化成数字0-25
            //如果这个点上没有标记,就说明没有存入过这个字符,所以返回0
            if(song[p][u] == 0) return 0;
            //如果这个点上面能寻找到这个字符,就让他往下一层继续寻找;
            p = song[p][u];
        }
        //最后查找完之后输出最后一个做标记的点为下标的cnt数组的值。
        return cnt[p];
    }
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        String sss = scan.nextLine();
        while(n -- > 0){
            String s = scan.nextLine();
            String[] st = s.split(" ");
            String s1 = st[0];
            String s2 = st[1];
            if(s1.equals("I")){
                insert(s2.toCharArray());
            }else{
                System.out.println(query(s2.toCharArray()));
            }
        }
    }
}

AcWing 143. 最大异或对

import java.io.*;
public class Main{
    static int N = 3100010,idx = 0;
    static int[][] song = new int[N][2];
    //插入
    public static void add(int x){
        int p = 0;//从头结点开始
        for(int i = 30 ; i >= 0 ; i -- ){ //从第31位开始遍历
            int u = x >> i & 1;//取出第i位的二进制数
            //判断这一层是空的,就创建,然后赋值下标
            if(song[p][u] == 0) song[p][u] = ++idx;
            //我觉得这个idx不是代表1或0,二维数组的u才代表这一条路的节点数字
            p = song[p][u];//然后让往下前进一层
        }
    }
    //查询
    public static int query(int x){
        int p = 0,res = 0;//从根节点0开始;res存的是这条路径表示的数
        for(int i = 30; i>= 0 ; i --){
            int u = x >> i & 1; //取出第i位的二进制数
//如果该节点的u是0,则判断一下在这一层有没有跟他相反的0,这样方便找最大异或值
            if(song[p][1-u] != 0){ 
                res += (1 << i);//res就将该二进制位对应异或之后的最优解1每一位顺次加起来。因为是异或相反数就是1,这是最优解
                p = song[p][1-u];//然后往最优解那边前进一层。
            }else{//否则就没有 最优解的0匹配1,1匹配0,所以就异或之后的值是0
                //res += (0 << i);因为是0所以可以省略,
                p = song[p][u];//然后让他往不优解那边前进一层。
            }
        }
        return res;//最后返回异或之后的最大值res
    }
    public static void main(String[] args)throws IOException{
        BufferedReader re = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter wt = new BufferedWriter(new OutputStreamWriter(System.out));
        int n = Integer.parseInt(re.readLine());
        String[] s = re.readLine().split(" ");
        for(int i = 0 ; i < n ; i ++ ){
            add(Integer.parseInt(s[i]));
        }
        int res  = 0;
        for(int i = 0 ; i < n ; i ++ ){
            //因为输入的是字符串所以需要转成整形。然后每一次比较res的值谁大,然后将最大值重新赋值给res
            res = Math.max(res,query(Integer.parseInt(s[i])));
        }
        wt.write(res +" ");//最后输出res,因为快输出输出的是字符串,所以需要在后面加上“ ”;
        wt.close();
    }
}

并查集

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 836.合并集合

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

import java.io.*;

public class Main {
    private static int[] p = new int[(int) 10e5];

    private static int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split(" ");
        int n = Integer.parseInt(s[0]), m = Integer.parseInt(s[1]);
        for (int i = 0; i < n; i++) {
            p[i] = i;
        }
        while (m-- > 0) {
            s = reader.readLine().split(" ");
            if ("Q".equals(s[0])) {
                int x = Integer.parseInt(s[1]);
                int y = Integer.parseInt(s[2]);
               writer.write(find(x) == find(y) ? "Yes\n" : "No\n");
            } else {
                int x = Integer.parseInt(s[1]);
                int y = Integer.parseInt(s[2]);
                p[find(x)] = find(y);
            }
        }
          writer.flush();
    }
}

AcWing 837. 连通块中点的数量

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

import java.io.*;

public class Main {
    private static int[] p = new int[(int) 10e5];

    private static int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split(" ");
        int n = Integer.parseInt(s[0]), m = Integer.parseInt(s[1]);
         int[] size = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;
            size[i]=1;
        }
        while (m-- > 0) {
            s = reader.readLine().split(" ");
            if ("Q1".equals(s[0])) {//是否在同一块内
                int x = Integer.parseInt(s[1]);
                int y = Integer.parseInt(s[2]);
               writer.write(find(x) == find(y) ? "Yes\n" : "No\n");
            } else if ("Q2".equals(s[0])) {//同一块内有多少节点
                int x = Integer.parseInt(s[1]);
               writer.write(size[find(x)]+"\n");
            } 
            else {
                int x = Integer.parseInt(s[1]);
                int y = Integer.parseInt(s[2]);
                if(find(x) == find(y) ) continue;
                size[find(y)]+=size[find(x)];//别加反了
                p[find(x)] = find(y);
            }
        }
          writer.flush();
    }
}

AcWing 240.食物链

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 838.堆排序

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

import java.io.*;
public class Main{
    static int[] h=new int[100010];
    static int size;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split(" ");
        int n = Integer.parseInt(s[0]), m = Integer.parseInt(s[1]);
         s = reader.readLine().split(" ");
        for (int i = 1; i <= n; i++) {
            h[i]=Integer.parseInt(s[i-1]);
        //  writer.write(h[i]+"\n");
        } 
        
        size=n;
        for(int i=n/2;i>0;i--){
           down(i);
        }
         while(m-->0) {
            writer.write(h[1]+" ");
            h[1]=h[size];
            size--;
            down(1);
        } 
        writer.flush();
    }
    public static void down(int u){
        int t=u;
        if(u*2<=size&&h[u*2]<h[t]) t=u*2;
        if(u*2+1<=size&&h[u*2+1]<h[t]) t=u*2+1;
        if(t!=u){
            int tem=h[t];
            h[t]=h[u];
            h[u]=tem;
            down(t);
        }
    }
}

AcWing 839.模拟堆

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

哈希表

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

数据范围是1e9,所以需要先% 再加 再%

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 840.模拟散列表

拉链法(数组+单链表)

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

import java.io.*;
import java.util.Arrays;
public class Main{
    static int N=100003,idx=0;
    static int[] h=new int[N];
    static int[] e=new int[N];
    static int[] ne=new int[N];

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split(" ");
        int n = Integer.parseInt(s[0]);
        
        //数组赋初始值
        Arrays.fill(h, -1);
        while(n-->0){
            s = reader.readLine().split(" ");
            int x=Integer.parseInt(s[1]);
            if("I".equals(s[0])) {//插入
                insert(x);
            }else{
                if( find(x) )
                    writer.write("Yes\n");
                else  writer.write("No\n");
            }
        } 
        writer.flush();
        
    }
    public static void insert (int x){
        int k=(x%N+N)%N;
        e[idx]=x;
        ne[idx]=h[k];
        h[k]=idx++;
    }
    
     public static boolean find (int x){
        int k=(x%N+N)%N;
        for(int i=h[k];i!=-1;i=ne[i]){
            if(e[i]==x){
                return true; 
            }
        }
        return false;
    }
}
开放寻址法(蹲坑法)直接一个数组模拟蹲坑

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 841.字符串哈希 :快速判断两个字符串是否相等

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

unsigned long long 是2^64次 代替了%Q,溢出时相当于 自动取模

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法

import java.util.Scanner ;
public class Main{
    //开long型数组,本来是 前缀hash求完之后 % 2的64次方来避免 冲突,可能超过我们给的数组大小
    static int N = 100010,P = 131;//p是进制数,经验值
    static long[] h = new long[N];// 存放hash前缀值
    static long[] p = new long[N];// 存放p的n次方
    public static long get(int l,int r){
        //求l-r区间的hash值,要用h[r] - h[l-1] 位数不同需要让h[l-1]向左边移到跟h[r]对齐
        //如求1234的3-4区间位,1234 - 12,12左移然后就让12*10^(4-3+1)=1200, 相减= 34
        //本题是p进制,需要将上行公式中的10换成p就行
        //h[0] = 0
        //h[1] = h[i-1] * P + str[1] = 0*P+a = a
        //h[2] = a * P + b
        //h[3] = (a*P+b)*P+c = a*p[2]+b*P+c
        //h[4] = (a*p[2]+b*P+c)*P+d = a*p[3]+b*p[2]+c*P+d
        //比如abcd求3-4区间位,就是让h[d]-h[b],h[b]位数不用需要向左移对齐h[d],
        //h[2]*P^(4-3+1)=(a*P+b)*P^2 = a*P^3+b*P^2
        //然后 h[d] - h[b] 求34区间值,(a*p[3]+b*p[2]+c*P+d) - (a*P^3+b*P^2) = c*P+d
        return h[r] - h[l-1]*p[r-l+1];
    }
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();
        String s = scan.next();

        p[0] = 1;//p的0次方=1
        for(int i = 1 ; i <= n ; i++ ){
            p[i] = p[i-1] * P;//每一个下标对应P的多少次方
            //预处理公式 前缀哈希的值,P进制,中间*P    
            h[i] = h[i-1] * P + s.charAt(i-1);
        }

        while(m -- > 0){
            int l1 = scan.nextInt();
            int r1 = scan.nextInt();
            int l2 = scan.nextInt();
            int r2 = scan.nextInt();
            //判断两个区间是不是相同,用get的方法返回值一样说明区间的hash值是一样的
            if(get(l1,r1) == get(l2,r2)) System.out.println("Yes");
            else System.out.println("No");
        }
    }
}

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表,Java从入门到起飞,python,java,算法文章来源地址https://www.toymoban.com/news/detail-613819.html

到了这里,关于AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【AcWing算法基础课】第五章 动态规划(未完待续)

    本专栏文章为本人AcWing算法基础课的学习笔记,课程地址在这。如有侵权,立即删除。 dp问题的优化 :在基本形式dp上作等价变形。 dp问题的解题方法 : 1)状态表示 集合 属性:最大值/最小值/数量。 2)状态计算 集合划分(不重不漏) 题目链接: 2. 01背包问题 - AcWing题库

    2024年02月12日
    浏览(31)
  • 算法基础课——基础算法(模板整理)

     快速排序 快速排序 第K个数 归并排序   归并排序 逆序对的数量 二分   数的范围 数的三次方根 高精度   高精度加法 Python一行就可以解决 高精度减法 高精度乘法 高精度除法 前缀和与差分 前缀和 子矩阵的和 差分 差分矩阵 双指针算法 最长连续不重复子序列 数组元素的目

    2024年02月12日
    浏览(28)
  • 算法基础课-搜索与图论

    题目链接:842. 排列数字 - AcWing题库 思路:写的很好的题解AcWing 842. 排列数字--深度优先遍历代码+注释 - AcWing 也可以考虑使用c++自带的next_permutation函数直接秒了: 题目链接:844. 走迷宫 - AcWing题库 思路:由于bfs是一层一层扩展,所以能保证走到终点时,走过的距离最短,所

    2024年04月15日
    浏览(38)
  • 算法基础课第五讲 动态规划

    时间复杂度:状态数量 转移的计算量 * 总体概述:给一堆物品,有体积有价值。有一个背包,在背包能装下的前提下最终能装下多少(背包不一定要装满) DP问题:一般需要从两方面考虑:状态表示以及状态计算 状态表示:f(i,j) 从两个方面考虑:集合(所有选法的集合)(

    2024年02月01日
    浏览(27)
  • 【algorithm】算法基础课---二分查找算法(附笔记 | 建议收藏)

    🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝 📣系列专栏:AcWing算法学习笔记 💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊 ✉️ 如果无聊的话,就来逛逛我的博客栈吧 stack-frame.cn 关于我

    2024年01月18日
    浏览(25)
  • Hadoop大数据开发基础课后答案

    本书为中国工信出版集团的《Hadoop大数据开发基础》 一、选择题 1.HDFS中的文件块默认保存(C)份。 B.2 A.1 C.3 D.不确定 2.启动集群的顺序为(A) ① start-dfs.sh ② start-yarn.sh ③ mr-jobhistory-daemon.sh start historyserver A.① ② ③ B.② ① ③ C.③ ② ① D.③ ① ② 3.关闭集群的顺序为(B)

    2024年02月07日
    浏览(29)
  • 基础课14——语音识别

    ASR 是自动语音识别 (Automatic Speech Recognition)的缩写,是一种将 人类语音转换为文本的技术 。ASR 系统可以处理实时音频流或已录制的音频文件,并将其转换为文本。它是一种自然语言处理技术, 广泛应用于许多领域, 包括电话语音助手、语音转文本、语音搜索等。 ASR 的工

    2024年02月03日
    浏览(27)
  • java基础课后习题答案

    一、 1.对象 2.面向对象、跨平台性 3.javac 4.Java虚拟机(或JVM) 5.JRE 二、 1.错 2.错 3.错 4.对 5.对 三、 1.C 2.ABCD 3.D 4.ABD 5.D 四、 1.简答性、面向对象、安全性、跨平台性、支持多线程、分布性。 2. Java程序运行时,必须经过编译和运行两个步骤。首先将后

    2024年01月21日
    浏览(30)
  • 基础课21——知识库管理

    智能客服中的知识库是一个以知识为基础的系统,可以明确地表达与实际问题相对应的知识,并构成相对独立的程序行为主体,有利于有效、准确地解决实际问题。它储存着机器人对所有信息的认知概念和理解,这些信息以数据的形式储存在数据库中,在需要的时候匹配地调

    2024年02月05日
    浏览(32)
  • 基础课18——智能客服系统架构

    基础设施主要包括以下几点: 1. 硬件设施 :包括服务器、存储设备、网络设备等,这是整个系统运行的物理基础。 2. 软件设施 :包括操作系统、数据库管理系统、自然语言处理(NLP)工具和机器学习算法等,这些是构建智能客服系统不可或缺的软件元素。 3. 数据设施 :包括

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包