据说华为的一道面试题
刷微博,看到一道面试题:
先说一下思路
默认题意为不能取重复的数字
总体来说,就是从可行解空间[1,1]~[20,20]中,逐步过滤,找到最终答案的过程。说一下过滤步骤:
- 首先A不确定两个数字,所以两数之和sum满足:4<=sum<=38
- 其次B也不确定,所以两数之积的分解方式可能有多种(本来以为可以用质因子个数>2来判别的,但是后来发现还要考虑两数在1到20之间)
- A知道数字了,所以sum的所有分解方式中,只有一个是让B不能确定的,即i+j=sum,切i*j的分解方式不止一种
- 这一步比较难:B知道乘积prod,对于prod分解的所有可能,都能得到其和sum,如果sum的所有分解中,只有一个是让B不能确定的;而且prod的分解只有一个是满足此关系的。则当前的prod,以及对应的让B不能确定的prod分解,即为所求解。
1和2很容易理解。3的话,如果sum的诸多分解方式中,都能被B确定,即i*j只能唯一分解,那B就不会说不知道数字了。如果sum的诸多分解方式中,有多个不能被B确定,那A在第三步就不能确定数字了,因为A拿不准B是在哪一组i*j中。
4,B知道乘积prod,假设可以分解为 I_n, J_n 。对于每一组 I_n, J_n: 和为sum=I_n+J_n,且A知道这个sum,这时B推测sum可以分解为i_n+j_n: 由于3的结论,所以sum对应的i_n*j_n的分解不唯一的情况只有一个 如果sum对应的i_n*j_n分解不唯一的情况为0个,那么B在第二步就可以猜出 如果sum对应的i_n*j_n分解不唯一的情况多于1个,那么A在第三步就猜不出来了 在所有的 I_n, J_n 中,满足如上条件的只有一个 如果都满足上述条件的多于一个,那么B在最后一步就无法确定哪一组I_n,J_n是正确答案了
当然,第四步也是在第三步的结果上过滤的
好,接下来就是写代码了
代码
// from http://www.robberphex.com/interview-question-from-huawei/ import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, List<List<Integer>>> sumCount = new HashMap<>(); Map<Integer, List<List<Integer>>> prodCount = new HashMap<>(); Set<List<Integer>> candidates = new HashSet<>(); for (int i = 1; i <= 20; i++) { for (int j = i + 1; j <= 20; j++) { // 第一步,A猜不出来 if (i + j < 4 || i + j > 38) { continue; } List<List<Integer>> sumCnt = sumCount.getOrDefault(i + j, new ArrayList<>()); sumCnt.add(Arrays.asList(i, j)); sumCount.put(i + j, sumCnt); List<List<Integer>> prodCnt = prodCount.getOrDefault(i * j, new ArrayList<>()); prodCnt.add(Arrays.asList(i, j)); prodCount.put(i * j, prodCnt); } } for (Map.Entry<Integer, List<List<Integer>>> entry : sumCount.entrySet()) { // 第二步,B猜不出来 int cnt = 0; List<Integer> res = null; if (entry.getValue().size() > 1) { for (List<Integer> list : entry.getValue()) { if (prodCount.get(list.get(0) * list.get(1)).size() > 1) { res = list; cnt++; } } } // 第三步,A猜出来了 if (cnt == 1) { candidates.add(res); } } //第四步,从第三步拿到的candidates中,过滤 for (List<Integer> num : candidates) { int poss = 0; for (List<Integer> prodNum : prodCount.get(num.get(0) * num.get(1))) { int cnt = 0; for (List<Integer> sumNum : sumCount.get(prodNum.get(0) + prodNum.get(1))) { if (prodCount.get(sumNum.get(0) * sumNum.get(1)).size() > 1) { cnt++; } } if (cnt == 1) { poss++; } } if (poss == 1) { System.out.println(num); } } } }
答案
算出来的答案有三组:
[2, 3]
[2, 4]
[9, 20]
当然,也有人说如果可以取重复的数字呢,那么只需要修改第11行就可以了,这时答案变为:
[2, 2]
[9, 20]
当然,这个思路也仅仅是我不成熟的想法,我也很难完整的证明这个解法是正确的。如果发现其中有错误的地方,请评论指出,谢谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Java研发面试99题(含答案):JVM+Spring+MySQL+线程池+锁
这篇文章主要介绍了Java研发面试99题,主要包括了JVM,Spring,MySQL,线程池,锁等,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-07-16- JS 初学者总是对this关键字感到困惑,因为与其他现代编程语言相比,JS 中的这this关键字有点棘手。今天小编给大家带来10个比较流行的JavaScript面试题 ,感兴趣的朋友一起2019-07-12
2019校招Java 开发岗面试知识点解析(附最新笔面试题)
这篇文章主要介绍了2019校招Java 开发岗面试知识点解析(附最新笔面试题),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-05-27- 这篇文章主要介绍了面试必备之Java 最常见 200+ 面试题全解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-05-13
- 之前过了几个简单的简历面,所以总结了几套面试的试题供大家分享。小编觉得挺不错的,也给大家做个参考。一起跟随小编过来看看吧2019-04-25
- 又到了面试求职高峰期,最近有很多网友都在求大厂面试题。这些题目是网友去百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目,发上来2019-04-24
- 面试一直是大家关注的问题,包括最近有很多人跟我讲投了很多简历出去,就像泥牛入海一样了无音讯了,今天我就来分享一个Java程序员面试拼多多后端开发岗位的几轮面试题。2019-04-24
精选11道Java技术面试题及对应答案【包含部分阿里和华为的面试题】
这篇文章主要为大家介绍了11道Java技术面试题及对应答案,其中包含部分阿里和华为的面试题,总结分析了java常见的技术难点与java常见面试题,需要的朋友可以参考下2019-04-11- 最近正值春招, 本文就把收集平时遇到的 Java 技术问题或周围朋友见过的面试题分享给大家,题库中所有的问题请看下文,考验你水平的时候到了。感兴趣的可以了解一下2019-04-11
- JVM(Java 虚拟机)算是面试必问的问题的了,而但凡问 JVM 一定会问的第一个问题就是:讲一讲 JVM 的组成?那本文就注重讲一下 JVM 的组成,感兴趣的可以了解一下2019-04-10
最新评论