美团笔试之编程题

有一个长为n的数组A,求满足0≤a≤b<n的A[b]-A[a]的最大值。
给定数组A及它的大小n,请返回最大差值。
class LongestDistance {
public:
    int getDis(vector<int> A, int n) {
        // write code here
        int max_dis = 0;
int min_num = A.at(0);
int dis;
        for(int i=0; i<n; i++){
          for (int j=i+1; j<n; j++){
            dis = A.at(j) - A.at(i);
            if(dis > max_dis){
                max_dis =dis;
            }
         }
        }
            
return max_dis;
    }
};


在4x4的棋盘上摆满了黑白棋子,黑白两色的位置和数目随机其中左上角坐标为(1,1),右下角坐标为(4,4),现在依次有一些翻转操作,要对一些给定支点坐标为中心的上下左右四个棋子的颜色进行翻转,请计算出翻转后的棋盘颜色。
给定两个数组A和f,分别为初始棋盘和翻转位置。其中翻转位置共有3个。请返回翻转后的棋盘。
测试样例:
[[0,0,1,1],[1,0,1,0],[0,1,1,0],[0,0,1,0]],[[2,2],[3,3],[4,4]]
返回:[[0,1,1,1],[0,0,1,0],[0,1,1,0],[0,0,1,0]]


import java.util.*;


public class Flip {
    public int[][] flipChess(int[][] A, int[][] f) {
        // write code here
        for(int i=0; i<f.length;i++){
            int tran_row = f[i][0] - 1;
            int tran_col = f[i][1] - 1;
            int tal_col = A.length-1;
            if(tran_row-1 >= 0)//上
            {
               A[tran_row-1][tran_col] = (A[tran_row-1][tran_col]==0)?1:0;
            }
            if(tran_row+1 <= tal_col)//下
            {
                 A[tran_row+1][tran_col] = (A[tran_row+1][tran_col]==0)?1:0;
            }
            if(tran_col -1 >=0)//左
            {
                A[tran_row][tran_col-1] = (A[tran_row][tran_col-1]==0)?1:0;
            }
           if(tran_col +1 <=tal_col)//右
            {
                A[tran_row][tran_col+1] = (A[tran_row][tran_col+1]==0)?1:0;
            }
        }
        return A;
        
    }
  
}


现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。
给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
方法一:
import java.util.*;


public class Visit {
    public int countPath(int[][] map, int n, int m) {
        // write code here
          // write code here
        int sale_row = 0;
        int sale_col = 0;
        int bus_row = 0;
        int bus_col = 0;
       // int[][] plan = new int[n][m];
        for(int i=0; i<n; i++){
            for(int j=0; j< map[i].length; j++){
                if(map[i][j] == 1){
                    sale_row = j;
                    sale_col = i;
                }if(map[i][j] == 2){
                    bus_row = j;
                    bus_col = i;
                }
            }
        }
        
        int xgo = sale_row>bus_row?-1:1;//根据商家的位置判断向左还是向右
        int ygo = sale_col>bus_col?-1:1;//向下还是向上
        
        for(int y=sale_col; y!=(bus_col+ygo); y+=ygo)
            {
            for(int x=sale_row; x!=(bus_row+xgo); x+=xgo){
                if(y==sale_col||x==sale_row){
                    map[y][x] = 1;
                    continue;
                }
                map[y][x] = map[y-ygo][x] + map[y][x-xgo];
            }
        }
         return map[bus_col][bus_row];
         
      }
    }


方法二:
import java.util.*;


public class Visit {
    public int countPath(int[][] map, int n, int m) {
        // write code here
          // write code here
        int sale_row = 0;
        int sale_col = 0;
        int bus_row = 0;
        int bus_col = 0;
        int[][] plan = new int[n][m];
        for(int i=0; i<n; i++){
            for(int j=0; j< map[i].length; j++){
                if(map[i][j] == 1){
                    sale_row = i;
                    sale_col = j;
                }if(map[i][j] == 2){
                    bus_row = i;
                    bus_col = j;
                }
            }
        }
       int xgo = sale_row>bus_row?-1:1;//根据商家的位置判断向左还是向右
       int ygo = sale_col>bus_col?-1:1;//向下还是向上
        
       for(int x=sale_row; x!=(bus_row+xgo); x+=xgo){
           for(int y=sale_col; y!=(bus_col+ygo); y+=ygo){
               if(x==sale_row||y==sale_col){
                   plan[x][y] = 1;                       
               }else if(x==sale_row){
                   plan[x][y] = (map[x][y] == -1)?0:plan[x][y-ygo];
               }else if(y==sale_col){
                   plan[x][y] = (map[x][y] == -1)?0:plan[x-xgo][y];
               }else{
                   plan[x][y] = (map[x][y] == -1)?0:(plan[x][y-ygo]+plan[x-xgo][y]);
               }
               
           }
       }
        return plan[bus_row][bus_col];
         
      }
    }


有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。
给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
测试样例:
[2,7,9,4,1],5
返回:14
import java.util.*;


public class MaxInnerRec {
    public int countArea(int[] A, int n) {
        // write code here
        int maxArea = 0;
        int min;
        for(int i=0; i<n; i++){
            min = Integer.MAX_VALUE;
            for(int j=i; j>=0; j--){
                min = Math.min(min, A[j]);
                maxArea= Math.max(maxArea,(i-j+1)*min);
            }
        }
        return maxArea;
        
    }
}


求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod 1000007。
输入描述:
每组数据包涵s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)


输入例子:


ab ce 1 2


输出例子:


56


import java.util.*;
public class Main{
    public static void main(String []args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            long result = 0;
            String begin = sc.next();
            String end = sc.next();
            int len1 = sc.nextInt();
            int len2 = sc.nextInt();
            int maxlen = begin.length()>end.length()?begin.length():end.length();
            int minlen = begin.length()<end.length()?begin.length():end.length();
            for(int i=0;i<maxlen;i++){
                int distance;
                if(i<minlen){
                    distance = end.charAt(i)-begin.charAt(i);
                     
                }else{
                    if(begin.length()>end.length())
                        distance = 'a' - begin.charAt(i)-1;
                    else
                        distance = end.charAt(i)-'a'+1;
                }
                long now=0;
                for(int j=len1;j<=len2;j++){
                    if(j-i-1>=0){
                        now=now+(long)Math.pow(26,j-i-1);
                    }
                }
                now = (now*distance)%1000007;
                result+=now;
            }
            System.out.println(result-1);
        }
    }
}
已知某公司总人数为W,平均年龄为Y岁(每年3月末计算,同时每年3月初入职新人),假设每年离职率为x,x>0&&x<1,每年保持所有员工总数不变进行招聘,新员工平均年龄21岁。 
从今年3月末开始,请实现一个算法,可以计算出第N年后公司员工的平均年龄。(结果向上取整)。 
输入例子:


5 5 0.2 3


输出例子:


15
import java.util.Scanner;
 
public class Main{
    //这个题着实让我弄了好一会,首先有三个误区,
    //第一个误区,每年在招纳新员工的同时,老员工的年龄是要增长的
    //第二个误区,为什么最后的公式与 W 无关。
    //第三个误区,是这个向上取整,题目给出的用例是5 5 0.2 3
    //然后我计算第一年的平均年龄是9,不用取整。
    //然后计算第二年的平均年龄是11.4,这时候我直接向上取整了,变成了12
    //所以下一年的平均年龄我误以为是12+1,导致我的计算结果不符合
    //其实题目是想让你把最后一年计算出来的年龄向上取整。
    //下面看一下代码
    public static int Average(int W ,double Y ,double x ,int N){
        //W表示公司总人数,Y表示当年平均年龄,x表示离职率,N表示多年以后
        for(int i = 0 ; i < N ; i++){
            //原始公式是这个Y = ((Y+1)*(W-W*x) + 21*(W*x))/W;
            //先求的离职之后还没有纳新时所有员工的总年龄,
            //记得Y+1,老员工也是要长大的
            //求得老员工的总年龄,然后加上纳新的员工的总年龄
            //最后除去公司的总人数,就是当年公司的平均年龄。
            //这个年龄是不进行向上取整的,而且我们发现这个公式是可以化简的
            //*************************************
            //下面是化简之后的公式,可以发现公式是与W没有关系的,
            //这就是为啥有的人纳闷为啥别人直接给出公式为啥与W无关,
            //但是自己又感觉最后公式肯定与W有关的原因了。
            //所以传参的时候可以不用传W。此处只是为了说明,
            Y = (Y+1)*(1-x)+21*x;
        }
        //最后对求得的结果进行向上取整。返回就OK了
        return (int) Math.ceil(Y);
    }
     
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        do{
            int W = sc.nextInt();
            double Y = sc.nextDouble();
            double x = sc.nextDouble();
            int N = sc.nextInt();
            System.out.println(Average(W,Y,x,N));
        }while(sc.hasNext());
    }
}


请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。




输入例子:


MT-TECH-TEAM


输出例子:


33


import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String value = sc.next();
            int minLen = hafuman(value);
            System.out.println(minLen);
        }
    }
    private static int hafuman(String val){
           //首先找出每个字符的个数
    char[] chars = val.toCharArray();
       Map<Character, Integer> map = new HashMap<>();
         for(int i=0; i<chars.length; i++){
        if(map.containsKey(chars[i])){
        map.put(chars[i], map.get(chars[i])+1);
        }else{
        map.put(chars[i], 1);
        }
       
       }
       
       //优先队列(最小推),每次能得到weigh最小的node
       Queue<TreeNode> q = new PriorityQueue<>(map.size(), new Comparator<TreeNode>() {
           @Override
           public int compare(TreeNode o1, TreeNode o2) {
               return Integer.compare(o1.weight, o2.weight);
           }
       });
       for (Map.Entry<Character, Integer> entry : map.entrySet()) {
           q.offer(new TreeNode(entry.getValue(), entry.getKey()));
       }
       while (q.size() > 1) {
           //弹出两个最小的,合并为一个node
           TreeNode left = q.poll();
           TreeNode right = q.poll();
           TreeNode father = new TreeNode(left.weight + right.weight);
           father.left = left;
           father.right = right;
           q.offer(father);
       }
       TreeNode root = q.poll();
       //计算长度     
       return valLength(root, 0);

   }
   
   public static int valLength(TreeNode node, int depth) {
       if (node == null) return 0;//仅计算ch有值的
       return (node.ch == null ? 0 : node.weight) * depth + valLength(node.left, depth + 1) + valLength(node.right, depth + 1);
   }
 
   static class TreeNode {
       int weight;//权重,出现次数
       Character ch;//如果是初始字符,则ch为字符,如果是合并的,则为null
       TreeNode left;
       TreeNode right;
 
       public TreeNode(int weight) {
           this.weight = weight;
       }
 
       public TreeNode(int weight, Character ch) {
           this.weight = weight;
           this.ch = ch;
       }
   }
   
}
对于一个由0..n的所有数按升序组成的序列,我们要进行一些筛选,每次我们取当前所有数字中从小到大的第奇数位个的数,并将其丢弃。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。
import java.util.*;
    public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        
        while(sc.hasNext()){
            int n = sc.nextInt(); 
           // int[] num = new int[n+1];
            List<Integer> li= new ArrayList<Integer>();
            for(int i=0; i<=n; i++){
                 li.add(i);            
            }
            while(li.size() != 1){
                for(int i=0; i<li.size(); i++){
                    
                        li.remove(i);
                    
                }
            }
            System.out.println(li.get(0));
        }
          
    }
}
有一个二维数组(n*n),写程序实现从右上角到左下角沿主对角线方向打印。
给定一个二位数组arr及题目中的参数n,请返回结果数组。
测试样例:
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]],4
返回:[4,3,8,2,7,12,1,6,11,16,5,10,15,9,14,13]
import java.util.*;


public class Printer {
    public int[] arrayPrint(int[][] arr, int n) {
        // write code here
        int[] print = new int[n*n];
        int startX = 0;
        int index = 0;
        int startY = n-1;
        while(startX < n){
            int x = startX;
            int y = startY;
            while(x<n&&y<n)
                print[index++] = arr[x++][y++];
            if(startY>0)
                startY--;
            else
                startX++;
        }
        return print;
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值