阿里笔试题2021.8.16(模拟、小修改的并查集)

阿里笔试题2021.8.16

也是帮同学做的,给自己做的笔试题就猿辅导,还一面就挂,等会总结下面试问的几个问题

第一题:计算变量的大小

题目描述

在这里插入图片描述
在这里插入图片描述

思路

简单的模拟思路,把字符串分割以后计算长度就行了

import java.util.*;
public class Main{

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        //String s = "long a[10][10][10],b,xyz";
        Map<String, Integer> map = new HashMap<>();
        map.put("int", 4);
        map.put("char", 2);
        map.put("long", 8);

        String[] ss = s.split(" ");
        int len = map.get(ss[0]);
        String[] strs = ss[1].split(",");
        //System.out.println(strs[0]);
        int l = strs.length;
        int res = 0;
        for(int i = 0; i < l; i++){
            String str = strs[i];
            int ls = str.length();
            int idx = 0;
            List<Integer> list = new ArrayList<>();
            while(idx < ls){
                if(str.charAt(idx) == '[') {
                    int num = 0;
                    idx++;
                    while (str.charAt(idx) >= '0' && str.charAt(idx) <= '9'){
                        num = num * 10 + str.charAt(idx) - '0';
                        idx++;
                    }
                    list.add(num);
                }
                idx++;
            }
            if(list == null){
                res += len;
                continue;
            }
            int t = 1;
            for(int n : list){
                t *= n;
            }
            res += t * len;
        }

        System.out.println(res);

    }
}

第二道:部队合并

题目描述

在这里插入图片描述
在这里插入图片描述

思路

思路就是合并两个部队用并查集来合并,与普通并查集不同的一点是,在并查集中多加一个变量count,存储每个部队(这个编号的联盟)的人数,合并的话就是把两个部队的人加到小编号的那个部队中。
不过这里花费的计算我没看懂到底是算联盟的还是算部队的,这里根据例子可以改一下,但是又没拍例子,只能写成差不多这样了
查询就是正常并查集的查询

不知道对不对,

import java.util.*;
public class Main{


    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] people = new int[n];
        for(int i = 0; i < n; i++){
            people[i] = sc.nextInt();
        }
        int[][] cmd = new int[m][3];
        for(int i = 0; i < m; i++){
            cmd[i][0] = sc.nextInt();
            cmd[i][1] = sc.nextInt();
            cmd[i][2] = sc.nextInt();
        }

        UnionFind uf = new UnionFind(n, people);
        for(int i = 0; i < m; i++){
            if(cmd[i][0] == 1){
                int px = uf.find(cmd[i][1]);
                int py = uf.find(cmd[i][2]);
                if(px == py)
                    continue;
                int countx = uf.count[px];
                int county = uf.count[py];
                int cost = (cmd[i][0] + cmd[i][1]) ^ Math.abs(countx - county);
                System.out.println(cost);
                uf.union(cmd[i][1], cmd[i][2]);
            }
            if(cmd[i][0] == 2)
                System.out.println(uf.query(cmd[i][1], cmd[i][2]) ? "YES" : "NO");
        }

    }
}

class UnionFind{
    int[] parents;
    int n;
    int[] count;
    //构造器
    public UnionFind(int n, int[] people){
        this.n = n;
        parents = new int[n];
        count = people;
        for(int i = 0; i < n; i++){
            parents[i] = i;
        }
    }

    public void union(int x, int y) {
        int px = find(x);
        int py = find(y);
        if(px == py)
            return;
        //如果父节点的编号小,将部队给了小的编号
        if(px < py){
            parents[py] = px;
            count[px] += count[py];
        }else{
            parents[px] = py;
            count[py] += count[px];
        }
    }

    public int find(int x){
        if(x != parents[x]){
            parents[x] = find(parents[x]);
        }
        return parents[x];
    }
    //查询x和y是否连通
    public boolean query(int x, int y){
        return find(x) == find(y);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值