微软20220819笔试(附JAVA代码)

感觉不是很难,等晚上笔试结束再贴一下自己的代码~

第一题

题目:

一个二维坐标系,给了两个数组X[],Y[],(X[i],Y[i])代表一个坑,现在有填坑的机器,宽度为W。每次可以沿着平行Y轴的方向修坑。问最少几次可以修完所有的坑。

思路:

类似力扣戳气球,贪心算法,每个坑都一定要修的,每次都选当前剩余的坑中第一个坑作为开始的起点x,这样以x+W以内的坑都能被修好,下次只要考虑X+W以外的坑的情况。

代码:

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.*;


public class Q1 {
    public static void main(String[] args) {
        int X[] = new int[]{2,4,2,6,7,1};
        Q1 q = new Q1();
        System.out.println(q.solution(X,null,2));
    }

    //每次第一个点都要修复,假设为i,那[i,i+W] 必然要修复,修复完考虑[i+W+1,正无穷的],又转换成刚才的问题,第一个点一定要修复
    public int solution(int[] X, int[] Y, int W) {
        if(X.length == 0) return 0;
        Arrays.sort(X);
        int end = X[0]+W;
        int ans = 1;
        int i = 1;
        while(i < X.length){
            System.out.println("当前坐标:"+X[i]+"\t当前最大值:"+end);
            if(X[i]<=end){
                i++;
            }
            else{
                ans++;
                end = X[i]+W;
                i++;
            }
            System.out.println("\tans:"+ans);
        }
        return ans;
    }
}


第二题

题目

给定一个字符串S,只由字符'0'....'9'组成,求S中字符能组成的最大的回文串。

思路

也是贪心,先计算字符串中成对的字符的个数(0要特殊处理,因为如果其他数字没成对,0成对也必要,会有前导0的问题,比如"0000"的答案应该是0,而"0011"的答案应该是1001)
因为是回文串,先拼接左边的部分,最后将字符串反转再拼接到原字符串上即可。
然后每次都选择当前能成对的字符中最大值,如果是最后一位,根据情况可以选择单个字符中的最大值。

代码

import java.util.Random;

public class Q2 {
    public static void main(String[] args) {
        Q2 q = new Q2();
        Random r = new Random();
        for (int i = 0; i < 10; i++) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < 20; j++) {
                sb.append(r.nextInt(10));
            }
            System.out.println(sb+":"+q.solution(sb.toString()));
        }
    }

    public String solution(String S) {
        // write your code in Java 8 (Java SE 8)
        int nums[] = new int[10];
        int n = S.length();
        for (int i = 0; i < S.length(); i++) {
            nums[S.charAt(i)-'0']++;
        }
        int pairs = 0;//计算相同数字的对数
        for(int i = 9; i > 0; i--){
            pairs+= (nums[i]/2);
            System.out.println("nums["+i+"]"+nums[i]);
        }
        pairs+= (pairs>0? nums[0]/2 : 0);
        System.out.println("nums[0]"+nums[0]);
        //需要填的位数
        boolean hasSingle =!(pairs*2==n);
        int ansBit = pairs + (pairs*2==n?0:1);
        StringBuilder ans = new StringBuilder();
        for (int i = 0; i < ansBit; i++) {
            for(int j = 9; j >= 0 ;j--){
                if(nums[j]>=2){
                    ans.append(j);
                    nums[j]-=2;
                    break;
                }
                else if(nums[j]==1 && i==ansBit-1&&hasSingle){
                    ans.append(j);
                    nums[j]--;
                    break;
                }
            }
        }
        String reverse = new StringBuilder(ans).reverse().toString();
        if(!hasSingle){
            ans.append(reverse);
        }
        else{
            ans.append(reverse.substring(1,reverse.length()));
        }
        return ans.toString();
    }
}

第三题

题目

给定一个图,有N+1(0~N)个结点,N条边,任意两个结点都是联通的,现在0号结点是办公室,1到N号结点都分别住着一个人,他们都需要打车到办公室。一辆车最多可以坐5个人。每辆车每次从一个结点移动到相邻的节点都要费油1。求制定一个共乘计划,让所有的人到办公室所需的油最小。求最小油耗的值。

思路

后序遍历,从顶点和边的要求可以看出这是一棵树,问题可以转换为所有节点到根节点的最小油耗问题。要注意需要记录每个节点的人数,后面方便计算油耗。

代码

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.rmi.log.LogInputStream;

import java.util.HashMap;

import java.util.*;
public class Q3 {
    public static void main(String[] args) {
       // int A[] = new int[]{0,1,1};
        //int B[] = new int[]{1,2,3};
 //       int A[] = new int[]{1,1,1,9,9,9,9,7,8};
   //     int B[] = new int[]{2,0,3,1,6,5,4,0,0};
        int A[] = new int[]{0};
        int B[] = new int[]{1};
        Q3 q = new Q3();
        System.out.println(q.solution(A,B));
    }

    public int solution(int[] A, int[] B) {
        // write your code in Java 8 (Java SE 8)
        //建图
        int N = A.length;
        HashMap<Integer,List<Integer>> Graph = new HashMap<Integer, List<Integer>>();
        for (int i = 0; i <= N; i++) {
            Graph.put(i,new ArrayList<>());
        }
        for (int i = 0; i < N; i++) {
            List<Integer> list = Graph.getOrDefault(A[i],new ArrayList<>());
            list.add(B[i]);
            Graph.put(A[i],list);
            list = Graph.getOrDefault(B[i],new ArrayList<>());
            list.add(A[i]);
            Graph.put(B[i],list);
        }
        //后续遍历
        int visited[] = new int[N+1];//记录每个节点是否访问过
        int cnt[] = new int[N+1];//记录每个节点的人数
        return postOrder(visited,Graph,0,cnt);
    }

    public int postOrder(int[] visited,HashMap<Integer,List<Integer>> G, int v,int cnt[]){
        visited[v] = 1;
        List<Integer> list = G.getOrDefault(v,new ArrayList<>());
        int cost = 0;
        cnt[v] = 1;
        System.out.println("节点:"+v);
        //到当前节点的油耗等于 其他节点到他子节点的油耗和子节点到他的油耗之和
        for(int num:list){
            if(visited[num]==0){
                //其他节点到子节点的油耗
                cost += postOrder(visited,G,num,cnt);
                System.out.println("添加上子节点"+num+"所需油耗,总油耗"+cost);
                //子节点到他所需的油耗
                cost += (cnt[num]+4)/5;
                System.out.println("添加上子节点"+num+"到"+v+"所需油耗:"+(cnt[num]+4)/5+",总油耗"+cost);
                //记录当前节点的人数
                cnt[v] += cnt[num];
                System.out.println("添加上子节点"+num+"人数:"+cnt[num]+",总人数"+cnt[v]);
            }
        }
        System.out.println("节点"+v+"\t耗油:"+cost+"\t人数:"+cnt[v]);
        return cost;
    }
}


#笔试##微软笔试##微软##2023一起秋招吧##面经笔经#
全部评论
看着好难,大佬试试其他厂吗还?
点赞 回复 分享
发布于 2022-09-15 13:13 北京
点赞 回复 分享
发布于 2022-08-26 21:11 安徽
恒生电子股份有限公司,登录链接:campus.hundsun.com/campus/jobs 推荐码:ESKGVT
点赞 回复 分享
发布于 2022-08-20 09:25 陕西
大佬,请问第一题二分,第二题统计频率+拼接字符串 这个思路可以嘛
点赞 回复 分享
发布于 2022-08-19 21:59 安徽
是过样例就算过了么....
点赞 回复 分享
发布于 2022-08-19 21:09 北京
最后一题有大佬有思路嘛,求讲一哈
点赞 回复 分享
发布于 2022-08-19 21:08 河北

相关推荐

刘湘_passion:太强了牛肉哥有被激励到
点赞 评论 收藏
分享
评论
2
14
分享

创作者周榜

更多
牛客网
牛客企业服务