Alibaba SWE 实习岗 笔试题 JAVA

最近参与了一场阿里的软件开发实习岗的笔试,于是想将题目分享一下~

如果有啥更好的想法欢迎交流~

Here We Go!

题目一

小明现在有一个长度为 n 的不递减序列,现在你可以操作任意次(可以不进行操作) ,每一次操作可以让某一个位置上的数增加1,但是每一个位置的数最多只能操作一次,现在想问你通过这个操作,能让新产生的序列中最多有多少个不同的数(重复的数算1个)。

输入描述

每一个文件输入第一行输A一个整数T (1 < T < 1000),代1表有T组测试数据。接下来T组,每一组第一行输入一个整数n (1 < n
< 10^5)。接下来输入n个整数,a[i] (1 ≤ a[i] ≤ 2*n) 代表序列中的每一个元素。

数据保证每一个文件内n的总和不超过100000

输出描述

对于每一组测试数据,输出一个答案代表最多有多少个不同的整数。

示例输入

2
6
1 2 2 2 5 6
2
4 4

示例输出

5 2

示例说明

对于样例第一组:序列变为1,2,3,2,5,6,此时不同元素最多

对于样例第二组:将这两个数任意一个数进行处理即可

思路
因为是不递减序列,所以我们可以定义一个set集合,然后开始遍历序列,遍历过程中操作如下:

  1. 每当遍历一个数,先判断该数是否已在set集合;
  2. 如果该数在set集合中不存在,那么直接将该数加入set集合;
  3. 如果该数在set已存在集合中,那么不妨将这个数 +1 后再加入set;
  4. 遍历完序列后,set集合即为 “最多不同的元素” 的集合,集合容量大小作为返回值即可。

示例代码

public static int maxDiffNum(){
        // 此处省略输入数据的处理
        // seq即为非递减序列
        int[] seq = new int[]{1, 2, 2, 2, 5, 6};
        // 定义一个hashset
        Set<Integer> set = new HashSet<>();

        for(int num : seq){
            // 如果该数在set集合中不存在,那么直接将该数加入set集合
            // 否则将这个数 +1 后再加入set
            if(!set.contains(num)){
                set.add(num);
            }else{
                set.add(++num);
            }
        }
        // 最后返回set集合的大小
        return set.size();
    }

题目二

小明现在有两个数a和b,初始值均为n,现在小明有以下4个操作:

  1. 将数a变成a - 100,若为负数,则记作0
  2. 将数a变成a - 75,数b变成b - 25,若为负数,则记作0
  3. 将数a变成a - 50,数b变成b - 50,若为负数,则记作0
  4. 将数a变成a - 25,数b变成b - 75,若为负数,则记作0

假设 P(A) 代表数字a先变成0的概率,P(AB) 代表数字a,b同时变成0的概率,P(B) 代表数字b先变成0的概率。小明想知道 P(A) + P(AB)/2 的值是多少
已知每一个操作是独立的且等概率的

输入描述

每一个文件输入第一行输入一个整数T(1 ≤ T ≤ 1000),代表有T组测试数据
接下来T组,每一组第一行输入一个整数n(1 ≤ n ≤10^9),代表两个数字的初始值

输出描述

对于每一组测试数据,输出一个小数代表要求的概率,误差在10^-5均算正确。

示例输入

2
50
100

示例输出

0.62500000
0.71875000

思路

用深搜去遍历所有可能出现的情况,每次递归一个操作:每次遍历的结果可能是以下四种:

  1. a > 0 且 b > 0;
  2. a > 0 且 b ≤ 0;
  3. a ≤ 0 且 b > 0;
  4. a ≤ 0 且 b ≤ 0;

如果是情况1,则继续深度搜索四个操作;
如果是情况2,则将总的出现的情况+1;
如果是情况3,则将P(A)出现的情况+1;
如果是情况4,则将P(AB)出现的情况+1。

最后计算P(A)出现的情况次数占总次数的比例,以及P(AB)出现的情况次数占总次数的比例,根据题目要求概率相加即可。

示例代码

//初始P(A)和P(AB)的情况都是0
    public static int pa = 0;
    public static int pab = 0;
    public static int psum = 0;
    
    public static double computeProbability(int n){
        computeProbabilityDfs(n, n);
        double PA = pa;
        double PAB = pab;
        double PSUM = psum;
        return PA / PSUM + PAB / PSUM / 2;
    } 
    
    public static void computeProbabilityDfs(int a, int b){
        if(a < 0 || a == 0 && b > 0){
            ++psum;
            ++pa;
        }else if((a < 0 || a == 0) && (b < 0 || b == 0)){
            ++psum;
            ++pab;
        }else if(a > 0 && b > 0){
            computeProbabilityDfs(a - 100, b);
            computeProbabilityDfs(a - 75, b - 25);
            computeProbabilityDfs(a - 50, b - 50);
            computeProbabilityDfs(a - 25, b - 75);
        }else{
            ++psum;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值