这道题是华为大数据开发工程师的机试面试题,规定解答时长为一个半小时,首先需要写出本题的代码,不能翻阅资料和API,在华为机试的系统中会有摄像头视频监控,并且开发工具中没有任何的代码提示,包括java类的包也是需要自己手动导入。
本题的意思是:使用java语言,任意从键盘输入10个随机数字,数字范围为[-512,512],然后从这10个数中随机抽取三个数,将这三个数x,y,z带入公式:x²+xy-y²+z中,要求必须保证输出的结果为所有组合结果的最小值。深入理解此题意,这个题其实是考数学中的排列组合问题,首先,需要先在10个输入的随机数中随机抽取三个数,那么10个数中取3个数,在排列组合保证不重复的情况下,会有120种排列组合结果,然后需要将每三个数为一组的排列组合对应带入x,y,z中进行公式值计算,那么问题又来了,比如这三个数某一种组合结果为2 1 3,那么请问:x,y,z分别应该对应哪个值呢?刚开始你会想如果都是正数的情况下,x取最小值,而对y取最大值,z取中间值,这样就能保证该公式带入计算的结果值为最小值,但是如果有负数或者全为负数的情况下,这个还成立吗?所以,我们又需要对这三个数 2 1 3进行x,y,z的全排列组合,不重复的排列组合结果一共有6种,然后我们将每一种的组合的值分别对应到x,y,z中,然后去计算带入该公式后的最小值,将所有结果进行保存到List中,然后最终计算完成,进行升序排序,取List中的第一个,即为所有排列组合带入公式计算出来的最小值!
例如:
输入10个数为:1 1 1 1 1 1 1 1 1 3 ,那么将所有排列组合带入公式 x²+xy-y²+z 中,其最小值为 -4 ,注意:输入的10个数字可以是重复的数字!
下面我们将本题的两个难点先进行逐个解析:
① 从n个数中取k个数,然后求不重复的所有排列组合
② 给定n个数,然后求这n个数的全排列组合
package com.hlk.huawei;
import java.util.ArrayList;
/**
* @author huleikai
* @create 2019-11-28 21:03
*/
public class ExtractPermutation {
//临时保存结果的集合
private static ArrayList tmpList = new ArrayList<>();
//保存结果的字符串
private static StringBuffer extractPermutationResult = new StringBuffer();
/**
* 给一个长度为n任意数组,取其中k个数,求所有的排列组合
* @param index 首个索引下标
* @param count 每次取几个数,即数组指针
* @param arr 待取的长度任意数组
*/
public static void extractPermutation(int index,int count,int []arr) {
if(count > arr.length || arr.length <= 0){
System.out.println("随机取数个数不能大于数组的长度或者数组不能为空!");
return;
}
if(count == 1){
for (int i = index; i < arr.length; i++) {
tmpList.add(arr[i]);
for (Integer integer : tmpList) {
extractPermutationResult.append(integer).append(",");
}
extractPermutationResult.delete(extractPermutationResult.length()-1,extractPermutationResult.length()).append("|");
System.out.println(tmpList);
tmpList.remove((Object)arr[i]);
}
}else if(count > 1){
for (int i = index; i <= arr.length - count; i++) {
tmpList.add(arr[i]);
extractPermutation(i + 1,count - 1, arr);
tmpList.remove((Object)arr[i]);
}
}else{
return;
}
}
public static void main(String[] args) {
int [] arr = {0,1,2,3,4,5,6,7,8,9};
extractPermutation(0 ,3 ,arr);
System.out.println(extractPermutationResult);
}
}
运行结果如下:
[0, 1, 2]
[0, 1, 3]
[0, 1, 4]
[0, 1, 5]
[0, 1, 6]
[0, 1, 7]
[0, 1, 8]
[0, 1, 9]
[0, 2, 3]
[0, 2, 4]
[0, 2, 5]
[0, 2, 6]
[0, 2, 7]
[0, 2, 8]
[0, 2, 9]
[0, 3, 4]
[0, 3, 5]
[0, 3, 6]
[0, 3, 7]
[0, 3, 8]
[0, 3, 9]
[0, 4, 5]
[0, 4, 6]
[0, 4, 7]
[0, 4, 8]
[0, 4, 9]
[0, 5, 6]
[0, 5, 7]
[0, 5, 8]
[0, 5, 9]
[0, 6, 7]
[0, 6, 8]
[0, 6, 9]
[0, 7, 8]
[0, 7, 9]
[0, 8, 9]
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 2, 6]
[1, 2, 7]
[1, 2, 8]
[1, 2, 9]
[1, 3, 4]
[1, 3, 5]
[1, 3, 6]
[1, 3, 7]
[1, 3, 8]
[1, 3, 9]
[1, 4, 5]
[1, 4, 6]
[1, 4, 7]
[1, 4, 8]
[1, 4, 9]
[1, 5, 6]
[1, 5, 7]
[1, 5, 8]
[1, 5, 9]
[1, 6, 7]
[1, 6, 8]
[1, 6, 9]
[1, 7, 8]
[1, 7, 9]
[1, 8, 9]
[2, 3, 4]
[2, 3, 5]
[2, 3, 6]
[2, 3, 7]
[2, 3, 8]
[2, 3, 9]
[2, 4, 5]
[2, 4, 6]
[2, 4, 7]
[2, 4, 8]
[2, 4, 9]
[2, 5, 6]
[2, 5, 7]
[2, 5, 8]
[2, 5, 9]
[2, 6, 7]
[2, 6, 8]
[2, 6, 9]
[2, 7, 8]
[2, 7, 9]
[2, 8, 9]
[3, 4, 5]
[3, 4, 6]
[3, 4, 7]
[3, 4, 8]
[3, 4, 9]
[3, 5, 6]
[3, 5, 7]
[3, 5, 8]
[3, 5, 9]
[3, 6, 7]
[3, 6, 8]
[3, 6, 9]
[3, 7, 8]
[3, 7, 9]
[3, 8, 9]
[4, 5, 6]
[4, 5, 7]
[4, 5, 8]
[4, 5, 9]
[4, 6, 7]
[4, 6, 8]
[4, 6, 9]
[4, 7, 8]
[4, 7, 9]
[4, 8, 9]
[5, 6, 7]
[5, 6, 8]
[5, 6, 9]
[5, 7, 8]
[5, 7, 9]
[5, 8, 9]
[6, 7, 8]
[6, 7, 9]
[6, 8, 9]
[7, 8, 9]
package com.hlk.huawei;
/**
* @author huleikai
* @create 2019-11-29 10:32
*/
public class FullPermutation {
/**
* 给定一个字符串数组,求字符串数组中所有字符串的全排列组合结果
* @param arr 需要排列组合的字符串数组
* @param point 数组索引指针
*/
private static StringBuffer fullPermutationResult = new StringBuffer();
public static void fullPermutation(String arr[], int point) {
if (point == arr.length) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
fullPermutationResult.append(arr[i] + " ");
}
fullPermutationResult.append("|");
System.out.println();
}
for (int i = point; i < arr.length; i++) {
String temp1 = arr[point];
arr[point] = arr[i];
arr[i] = temp1;
fullPermutation(arr, point + 1);
String temp2 = arr[point];
arr[point] = arr[i];
arr[i] = temp2;
}
}
public static void main(String[] args) {
String[] strArr = new String[]{"12","-5","8"};
fullPermutation(strArr, 0);
fullPermutationResult.delete(fullPermutationResult.length()-1,fullPermutationResult.length());
System.out.println("================================");
String[] split = fullPermutationResult.toString().split("\\|", -1);
for (String s : split) {
System.out.println(s);
}
}
}
运行结果如下:
package com.hlk.huawei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
/**
* @author huleikai
* @create 2019-11-28 19:25
*/
public class HuaWeiTest {
/**
* 给定一个字符串数组,求字符串数组中所有字符串的全排列组合结果
* @param arr 需要排列组合的字符串数组
* @param point 数组指针
*/
private static StringBuffer fullPermutationResult = new StringBuffer();
public static void fullPermutation(String arr[], int point) {
if (point == arr.length) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
fullPermutationResult.append(arr[i] + " ");
}
fullPermutationResult.append("|");
System.out.println();
}
for (int i = point; i < arr.length; i++) {
String temp1 = arr[point];
arr[point] = arr[i];
arr[i] = temp1;
fullPermutation(arr, point + 1);
String temp2 = arr[point];
arr[point] = arr[i];
arr[i] = temp2;
}
}
private static ArrayList tmpList = new ArrayList<>();
//保存结果的字符串
private static StringBuffer extractPermutationResult = new StringBuffer();
/**
* 给一个长度为n任意数组,取其中k个数,求所有的排列组合
* @param index 首个索引下标
* @param count 每次取几个数,即数组指针
* @param arr 待取的长度任意数组
*/
public static void extractPermutation(int index,int count,int []arr) {
if(count > arr.length || arr.length <= 0){
System.out.println("随机取数个数不能大于数组的长度或者数组不能为空!");
return;
}
if(count == 1){
for (int i = index; i < arr.length; i++) {
tmpList.add(arr[i]);
for (Integer integer : tmpList) {
extractPermutationResult.append(integer).append(",");
}
extractPermutationResult.delete(extractPermutationResult.length()-1,extractPermutationResult.length()).append("|");
System.out.println(tmpList);
tmpList.remove((Object)arr[i]);
}
}else if(count > 1){
for (int i = index; i <= arr.length - count; i++) {
tmpList.add(arr[i]);
extractPermutation(i + 1,count - 1, arr);
tmpList.remove((Object)arr[i]);
}
}else{
return;
}
}
/**
* 返回随机输入的整数数组
* @return
*/
public static int[] getArray(){
int[] arr = new int[10];
int i = 0;
while (i < 10){
System.out.println("请随意输入十个整数,范围是[-512,512] :");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if (num > 512 || num < -512) {
System.out.println("您输入的数不合法,请输入一个范围在[-512,512]的整数!");
continue;
}
arr[i] = num;
i++;
}
return arr;
}
/**
* 指定的数组中随机抽取三个数,然后带入公式:x的平方+xy-y的平方+z中,
* 求出这十个数中随意随机出来的三个数带入这个公式的最小值
* @return
*/
public static int getResult(){
//存放每计算出来的三个随机数结果的集合
ArrayList resultList = new ArrayList<>();
//从数组长度为10的数组中随机取出3个数,排列组合最终拿到的组合结果数组
String[] combinationResult = extractPermutationResult.toString().split("\\|", -1);
for (String c : combinationResult) {
String[] strArr = c.split(",");
//对每个随机抽取出来的三位数进行全排列组合
fullPermutation(strArr,0);
//对每个随机抽取出来的三位数进行全排列组合之后的结果数组
String[] fullPermutationResultArr = fullPermutationResult
//去掉fullPermutationResult字符串拼接的最后一个"|"
.delete(fullPermutationResult.length()-1,fullPermutationResult.length())
.toString().split("\\|", -1);
for (String s : fullPermutationResultArr) {
String[] strNum = s.split(" ");
int x = Integer.parseInt(strNum[0]);
int y = Integer.parseInt(strNum[1]);
int z = Integer.parseInt(strNum[2]);
//带入华为题目中指定的公式对每个三位数组合进行结果值计算
int result = (int)(Math.pow(x,2) + x*y - Math.pow(y,2) +z);
//将每次计算的结果放入结果集合中进行保存
resultList.add(result);
}
}
//最终对结果集合进行升序排序
Collections.sort(resultList);
//返回所有排列组合计算出的最小结果值
return resultList.get(0);
}
public static void main(String[] args) {
int[] arr = getArray();
extractPermutation(0,3,arr);
int result = getResult();
System.out.println("结果是: "+result);
}
}
运行结果测试案例1:
运行结果测试案例2:
注:希望记录的意义,可以帮助到需要帮助的人,如果你觉得有什么问题可以私信我,谢谢!