美团2018校园招聘内推笔试代码分享

因为被美团的大佬翻牌子了,所以内推直接免笔试进面试,恰巧今天遇到同学们答美团的笔试题,热爱OJ的我就参与了一发,战果还不错,2道题都轻松AC了。

接下来就和大家分享一下我的做题思路和代码,我觉得第一题还有改进的地方,希望大家不吝赐教,我也今晚好好想想有没有更优秀的解法。

首先是第一题:

序列中任意个连续的元素组成的子序列称为该序列的子串。

现在给你一个序列P和一个整数K,询问元素和是K的倍数的子串的最大长度。

样例输入:

[1,2,3,4,5],整数K,满足条件的子串是{5},{2,3},{1,2,3,4},{1,2,3,4,5}。

那么答案就是5。如果这样的子串不存在,就输出0.

这道题和今年蓝桥杯上面的一道题很想(虽然我也没参加,只是自己随便做了做它的题)。适用动态规划,维护一个dp矩阵,每个元素是前面元素和%K的结果,注意,我们计算下一个元素时,只需要根据递推公式: dp[i] = (dp[i-1]+arr[i])%K;即可。比如[1,2,3,4,5]就会得到[1,3,1,0,0]。

这时候我们再根据这个dp矩阵来计算最大长度,dp矩阵中元素一定是0,1,...K-1.

先看0.为0就代表前面的元素和正好是K的倍数,那么我们寻找数组中最后一个0的位置,就是dp[i]=0的最长子串长度-1.

然后看1,我们找dp矩阵中第一1的位置j和最后一个1之间的位置k的差,这个差值就是dp[i]=1的最长子串长度。相当于前k项和-前j项和正好是K的倍数。

...

依次类推到K-1,每次都维护最长距离max。最终输出。

同时加入arr.length==0的判断。

package com.nowcoder.java;

public class Meituan01 {
	public static void main(String[] args) {
		int[] arr={1,2,3};
		int K = 5;
		System.out.println(cal(arr,K));
	}
	
	public static int cal(int[] arr,int K){
		if(arr.length==0)
			return 0;
		int max=0;
		int[] dp = new int[arr.length];
		dp[0] = arr[0]%K;
		for(int i=1;i<dp.length;i++){
			dp[i]=(dp[i-1]+arr[i])%K;
		}
		
		for(int i=0;i<dp.length;i++){
			if(dp[i]==0)
				max=i+1;
		}
		for(int i=1;i<K;i++){
			int pre = 0;
			int back = dp.length-1;
			while(dp[pre]!=i && pre<back)
				pre++;
			while(dp[back]!=i && back>pre)
				back--;
			int len=back-pre;
			if(len>max)
				max=len;
		}
		return max;
	}
}

第二题

太长了我直接贴图。


这道题乍看很难,其实道理只有一个!

那就是:最大的那一个组的人数一定要比其余组的和大于等于即可!

package com.nowcoder.java;

import java.util.Arrays;

public class Meituan02 {
	public static void main(String[] args) {
		int N=2;
		int[] arr = new int[]{10,10,20};
		System.out.println(check(arr,N));
	}
	public static boolean check(int[] arr,int N){
		if(N<=1)
			return false;
		Arrays.sort(arr);
		int sum = 0;
		for(int i=0;i<N-1;i++){
			sum+=arr[i];
		}
		if(sum>=arr[N-1])
			return true;
		else{
			return false;
		}
	}
}
代码如上,

以上


猜你喜欢

转载自blog.csdn.net/u013576018/article/details/77753327