华为OD机试(41-60)老题库解析&Java源码系列连载ing_华为java机试题库及答案

最后

终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

	if (!flag)
		System.out.println("结果为:-1");
}

public static int dfs(List<Integer> nums) {
	int objCount = nums.size();// 步数数量
	int stype = 0;// 第几步
	if (nums.get(0) <= 0) {// 第一个数 可能 负数或0 那么步子无法迈出去
		return -1;
	}
	for (stype = 1; stype < nums.size() / 2; stype++) {
		boolean f = false;// 第一步位stype 看下是否能移动到nums的最后一个成员
		int tempStype = stype;
		int index = 0;// 移动的索引
		int count = 0;// 一开始就第一步 后面每挪动一次就加1
		int tempCount = 0;
		while (tempStype < nums.size()) {
			index += tempStype;
			// System.out.println("index:"+index+" tempStype:"+tempStype);;
			count++;
			if (index == nums.size() - 1) {
				tempCount = count;
				// System.out.println("找到了,第一步为" + stype+"步数为"+count);
				f = true;
			} else if (index < nums.size()) {
				tempStype = nums.get(index);
			} else {
				// 越界了 没找到
				break;
			}
		}
		if (f) {
			flag = true;
			if (objCount > tempCount) {
				objCount = tempCount;
			}
		}

	}
	return objCount;
}

}


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/58fc2443a44d4a439a90e78e002d907b.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/1481c190696943eab2ff6869ceb5f747.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e329471b95a146b085401d2c25e73503.png)


### 49.执行时长


**题目描述**



> 
> 为了充分发挥GPU[算力]( ),需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。
> 
> 
> 假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。
> 
> 
> 


**输入描述**



> 
> * 第一个参数为GPU一次最多执行的任务个数,取值范围[1, 10000]
> * 第二个参数为任务数组长度,取值范围[1, 10000]
> * 第三个参数为任务数组,数字范围[1, 10000]
> 
> 
> 


**输出描述**



> 
> * 执行完所有任务最少需要多少秒。
> 
> 
> 


#### 用例




|  |  |
| --- | --- |
| 输入 | 3 5 1 2 3 4 5 |
| 输出 | 6 |
| 说明 | 一次最多执行3个任务,最少耗时6s |




|  |  |
| --- | --- |
| 输入 | 4 5 5 4 1 1 1 |
| 输出 | 5 |
| 说明 | 一次最多执行4个任务,最少耗时5s |



**解析**



> 
> 这个题目重在理解题,理解后可以使用递归进行问题解决  
>  例如下图 可以增强对这个题的执行过程理解  
>  ![在这里插入图片描述](https://img-blog.csdnimg.cn/b8d85a0b48c545be9bb73d70eac2fa2e.png)  
>  **示例代码**
> 
> 
> 



import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class T49 {
static List taskList = new ArrayList();
static int count = 0;

public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	int gpu = Integer.parseInt(sc.nextLine());
	int taskNum = Integer.parseInt(sc.nextLine());
	String strTask = sc.nextLine();
	for (String item : strTask.split(" ")) {
		taskList.add(Integer.parseInt(item));
	}
	deal(gpu, 0);
	System.out.println(count);
}

public static void deal(int gpu, int toDeal) {
	if (taskList.size() == 0 && toDeal == 0) {
		return;
	}
	if (taskList.size() == 0) {
		count++;
		if (gpu < toDeal) {
			toDeal = toDeal - gpu;
			deal(gpu, toDeal);
		}
	} else if (toDeal > 0) {
		count++;
		toDeal = taskList.get(0) + toDeal - gpu;
		if (toDeal < 0) {
			toDeal = 0;
		}
		taskList.remove(0);
		deal(gpu, toDeal);
	} else if (toDeal == 0) {
		toDeal = taskList.get(0) - gpu < 0 ? 0 : taskList.get(0) - gpu;
		count++;
		taskList.remove(0);
		deal(gpu, toDeal);
	}
}

}


**运行示例**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c37d9b1057064342a27156426c1c6e9f.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/15532ece0a9e4af88de6dd4b4d4eb910.png)


### 50.用户调度问题


**题目描述**



> 
> 在通信系统中,一个常见的问题是对用户进行不同策略的调度,会得到不同的系统消耗和性能。
> 
> 假设当前有n个待串行调度用户,每个用户可以使用A/B/C三种不同的调度策略,不同的策略会消耗不同的系统资源。请你根据如下规则进行用户调度,并返回总的消耗资源数。 
>  规则:
> 
> 
> 1.    相邻的用户不能使用相同的调度策略,例如,第1个用户使用了A策略,则第2个用户只能使用B或者C策略。
> 
> 
> 2.    对单个用户而言,不同的调度策略对系统资源的消耗可以[归一化]( )后抽象为数值。例如,某用户分别使用A/B/C策略的系统消耗分别为15/8/17。
> 
> 
> 3.    每个用户依次选择当前所能选择的对系统资源消耗最少的策略(局部最优),如果有多个满足要求的策略,选最后一个。
> 
> 
> 


**输入描述**



> 
> 第一行表示用户个数n
> 
> 
> 接下来每一行表示一个用户分别使用三个策略的系统消耗resA resB resC
> 
> 
> 


**输出描述**



> 
> 最优策略组合下的总的系统资源消耗数
> 
> 
> 


#### 用例




|  |  |
| --- | --- |
| 输入 | 3 15 8 17 12 20 9 11 7 5 |
| 输出 | 24 |
| 说明 | 1号用户使用B策略,2号用户使用C策略,3号用户使用B策略。系统资源消耗: 8 + 9 + 7 = 24。 |


**题目解析**



> 
> 这个题目有的人使用迭代去做,迭代的思想相对来说简单些。每次取出一个资源,并把索引记录下来。往下迭代产生结果。  
>  这个题为在解决的时候使用了动态规划算法。不熟悉的可以参考我的另一篇博客。  
>  [【算法】使用数位算法生成0至某个数之间的整数(for循环之外的另一种实现方式,蛮长见识的)]( )  
>  针对上述用例,用图可以展示为  
>  ![在这里插入图片描述](https://img-blog.csdnimg.cn/d7027009531147de83f36e70fa89a7be.png)  
>  其中黄线区域所连接的为不可达,因为题目要求**相邻的用户不能使用相同的调度策略**  
>  最后计算每个叶子节点路径和 并求出最小值即可。
> 
> 
> 


**示例代码java**



import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class T50 {
static int num[] = null;
static int minResouce = Integer.MAX_VALUE;// 资源最小

public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	int userNo = Integer.parseInt(sc.nextLine());
	List<List<Integer>> resourceList = new ArrayList<List<Integer>>();
	for (int i = 0; i < userNo; i++) {
		List<Integer> resList = new ArrayList<Integer>();
		Arrays.stream(sc.nextLine().split(" ")).forEach(s -> resList.add(Integer.parseInt(s)));
		;
		resourceList.add(resList);
	}
	num = new int[userNo];
	System.out.println(resourceList);
	dfs(0, resourceList, -1);
	System.out.println(minResouce);
}

/\*\*

*
* @param p 取第p个子列表
* @param resourceList 所有的资源List
* @param p1 上一个列表中取了哪一个索引
*/
public static void dfs(int p, List<List> resourceList, int p1) {
if (p >= resourceList.size()) {
// 计算
int sum = 0;
for (int r : num) {
sum += r;
System.out.print(r + " ");
}
if (sum < minResouce) {
minResouce = sum;
}
System.out.println();
return;
}
List itemList = resourceList.get§;
for (int i = 0; i < itemList.size(); i++) {
if (i == p1)
continue;
num[p] = itemList.get(i);
dfs(p + 1, resourceList, i); // i不能写成p 会产生错乱
}

}

}


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f676c8f45dfe40309a894f05d5ef379f.png)


### 51.查找众数及中位数


**题目描述**



> 
> 众数是指一组数据中出现次数量多的那个数,众数可以是多个。
> 
> 
> [中位数]( )是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数为偶数,那就把中间的两个数之和除以2,所得的结果就是中位数。
> 
> 
> 查找整型数组中元素的众数并组成一个新的数组,求新数组的中位数。
> 
> 
> 


**输入描述**



> 
> 输入一个一维整型数组,数组大小取值范围 0<N<1000,数组中每个元素取值范围 0<E<1000
> 
> 
> 


**输出描述**



> 
> 输出众数组成的新数组的中位数
> 
> 
> 


#### 用例




|  |  |
| --- | --- |
| 输入 | 10 11 21 19 21 17 21 16 21 18 15 |
| 输出 | 21 |




|  |  |
| --- | --- |
| 输入 | 2 1 5 4 3 3 9 2 7 4 6 2 15 4 2 4 |
| 输出 | 3 |




|  |  |
| --- | --- |
| 输入 | 5 1 5 3 5 2 5 5 7 6 7 3 7 11 7 55 7 9 98 9 17 9 15 9 9 1 39 |
| 输出 | 7 |


**题目解析**



> 
> 这个题属于逻辑题,先将输入的字符串解析成数组,然后转换到map中去,顺便把出现最多的次数记录下来。
> 
> 
> 遍历map将次数等于最多次数的数装入一个List
> 
> 
> 对List进行排序,排序后根据列表长度来确认中位数
> 
> 
> 


**示例代码Java**



import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

/**
* 求众数排列后的中位数 1.求众数 2.求中位数 10 11 21 19 21 17 21 16 21 18 15 2 1 5 4 3 3 9 2 7 4
* 6 2 15 4 2 4 5 1 5 3 5 2 5 5 7 6 7 3 7 11 7 55 7 9 98 9 17 9 15 9 9 1 39
*/
public class T51 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int max[] = new int[1];
Arrays.stream(sc.nextLine().split(" ")).forEach(s -> {
int key = Integer.parseInt(s);
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
if (max[0] < map.get(key)) {
max[0] = map.get(key).intValue();// 求出出现的最大次数
}
});
System.out.println(map);

	// 过滤
	Set<Integer> keySet = map.keySet();
	List<Integer> numList = new ArrayList<Integer>();
	Iterator<Integer> it = keySet.iterator();
	while (it.hasNext()) {
		Integer key = it.next();
		if (map.get(key) == max[0]) {
			for (int i = 0; i < map.get(key); i++) {
				numList.add(key);
			}
		}
	}
	System.out.println(numList);

	// 求中位数
	numList.sort(new Comparator<Integer>() {
		@Override
		public int compare(Integer arg0, Integer arg1) {
			if (arg0 < arg1)
				return -1;
			if (arg0 > arg1)
				return 1;
			return 0;
		}
	});
	int middle = numList.size() % 2 == 1 ? numList.get(numList.size() / 2)
			: (numList.get(numList.size() / 2) + numList.get(numList.size() / 2 - 1)) / 2;
	System.out.println(middle);
}

}


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d1025de70ff04621a85b6affa35b9619.png)


### 52.最大N个数与最小N个数的和


**题目描述**



> 
> 给定一个数组,编写一个函数来计算它的最大N个数与最小N个数的和。你需要对数组进行去重。
> 
> 
> 


说明:


* 数组中数字范围[0, 1000]
* 最大N个数与最小N个数不能有重叠,如有***重叠,输入非法***返回-1
* 输入非法返回-1


**输入描述**


* 第一行输入M, M标识数组大小
* 第二行输入M个数,标识数组内容
* 第三行输入N,N表达需要计算的最大、最小N个数


**输出描述**


输出最大N个数与最小N个数的和


**用例**





|  |  |
| --- | --- |
| 输入 | 5 95 88 83 64 100 2 |
| 输出 | 342 |
| 说明 | 最大2个数[100,95],最小2个数[83,64], 输出为342。 |






|  |  |
| --- | --- |
| 输入 | 5 3 2 3 4 2 2 |
| 输出 | -1 |
| 说明 | 最大2个数[4,3],最小2个数[3,2], 有重叠输出为-1。 |



**解析**



> 
> 典型的**逻辑处理**题型,需要掌握字符串拆分,排序等知识点。
> 
> 
> 


**示例代码Java**



import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

//5
//95 88 83 64 100
//2
public class T52 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List numList = new ArrayList<>();
int count = Integer.parseInt(sc.nextLine());
Arrays.stream(sc.nextLine().split(" ")).forEach(s -> {
if (!numList.contains(Integer.parseInt(s)))
numList.add(Integer.parseInt(s));
});

	numList.sort(new Comparator<Integer>() {
		@Override
		public int compare(Integer o1, Integer o2) {
			if (o1 > o2)
				return 1;
			if (o1 < o2)
				return -1;
			return 0;
		}
	});
	int num = Integer.parseInt(sc.nextLine());
	List<Integer> num1 = new ArrayList<>();
	num1 = numList.subList(0, num);
	System.out.println(num1);
	boolean flag = false;
	List<Integer> num2 = new ArrayList<>();
	num2 = numList.subList(numList.size() - num, numList.size());
	System.out.println(num2);
	for (int i = 0; i < num1.size(); i++) {
		if (num2.contains(num1.get(i))) {
			System.out.println("-1");
			flag = true;
			break;
		}
	}

	if (!flag) {
		int sum[] = new int[1];
		num1.stream().forEach(s -> {
			sum[0] += s;
		});
		num2.stream().forEach(s -> {
			sum[0] += s;
		});
		System.out.println(sum[0]);
	}

}

}


**代码运行示例**


![在这里插入图片描述](https://img-blog.csdnimg.cn/94a78f288aed439b9a9673d617cf537b.png)


### 53.最长连续子序列


**题目描述**


有N个正整数组成的一个序列。给定整数sum,求长度最长的连续[子序列]( ),使他们的和等于sum,返回此子序列的长度,


如果没有满足要求的序列,返回-1。




---


**输入描述**


第一行输入是:N个正整数组成的一个序列


第二行输入是:给定整数sum




---


**输出描述**


最长的连续子序列的长度


**备注**


* 输入序列仅由数字和英文逗号构成,数字之间采用英文逗号分隔
* 序列长度:1 <= N <= 200
* 输入序列不考虑异常情况


#### 用例




|  |  |
| --- | --- |
| 输入 | 1,2,3,4,2 6 |
| 输出 | 3 |
| 说明 | 1,2,3和4,2两个序列均能满足要求,所以最长的连续序列为1,2,3,因此结果为3。 |




|  |  |
| --- | --- |
| 输入 | 1,2,3,4,2 20 |
| 输出 | -1 |
| 说明 | 没有满足要求的子序列,返回-1 |


#### 题目解析


1. 使用双指针找到对相邻的数进行求和。若和正确,那么就判断长度是否比前面出现的长度都大,若大就进行记录。
2. 若和大于,那么就证明该区间内不存在目标序列。左指针右移,临和减掉移出的左侧的那个。
3. 若和小于,就证明该区间还可以往右扩充,右指针右移,临和加上移入的那一个。这样就避免了在内部在使用循环计算区间和了。



import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class T53 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
int sum = Integer.parseInt(sc.nextLine());
List numList = new ArrayList<>();
Arrays.stream(input.split(“,”)).forEach(s -> {
numList.add(Integer.parseInt(s));
});
int left = 0;
int right = 0;
int tempSum = numList.get(left);// 临时的区间和
int len = -1;
while (right < numList.size()) {
if (tempSum < sum) {
right++;
if (right == numList.size())
break;// 超出了
tempSum += numList.get(right);
// System.out.println(tempSum);
} else if (tempSum > sum) {
tempSum -= numList.get(left);
left++;
} else {
// System.out.println(right - left + “-”);
// System.out.println(right + “-----” + left);
if (len < right - left) {
len = right - left + 1;
}
tempSum -= numList.get(left);
left++;

		}
	}
	System.out.println(len);
}

}


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/29b99bfb42164f979899e0bf6a96fbb3.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/0b5f624caf24419eb33bfc0429d25e2f.png)


### 54.数组去重和排序


**题目描述**


给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。




---


**输入描述**


一个数组




---


**输出描述**


去重排序后的数组


#### 用例




|  |  |
| --- | --- |
| 输入 | 1,3,3,3,2,4,4,4,5 |
| 输出 | 3,4,1,2,5 |
| 备注 | 数组大小不超过100 数组元素值大小不超过100。 |





---


**题目解析**


使用List装入Map对象,每个map存储一个数字为键,值为键对应的出现的次数。最后再对List根据排序规则排序就可



import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class T54 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
List keyList = new ArrayList<>();// 记录顺序
Arrays.stream(input.split(“,”)).forEach(s -> {
Integer key = Integer.parseInt(s);
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
if (!keyList.contains(key)) {
keyList.add(key);
}
});
// System.out.println(map);
// System.out.println(keyList);
List<Map<Integer, Integer>> mapList = new ArrayList<>();
for (Integer key : keyList) {
Map<Integer, Integer> m = new HashMap<>();
m.put(key, map.get(key));
mapList.add(m);
}
mapList.sort(new Comparator<Map<Integer, Integer>>() {
@Override
public int compare(Map<Integer, Integer> m1, Map<Integer, Integer> m2) {
Integer v1 = m1.values().iterator().next();
Integer v2 = m2.values().iterator().next();
if (v1 > v2)
return -1;
if (v2 < v1)
return 1;
if (v2 == v1) {
// 取key顺序来判断
Integer k1 = m1.keySet().iterator().next();
Integer k2 = m2.keySet().iterator().next();
if (k1 > k2)
return 1;
if (k1 < k2)
return -1;
}
return 0;
}
});
mapList.forEach(m -> {
System.out.print(m.keySet().iterator().next() + “,”);
});
}
}




---


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e454fd28a67a4a05a66beda53b6b9d7a.png)


### 55.数组拼接


**题目描述**


现在有多组整数数组,需要将它们合并成一个新的数组。


合并规则,从每个数组里按顺序取出固定长度的内容合并到新的数组中,取完的内容会删除掉,如果该行不足固定长度或者已经为空,则直接取出剩余部分的内容放到新的数组中,继续下一行。


**输入描述**


第一行是每次读取的固定长度,0 < 长度 < 10


第二行是整数数组的数目,0 < 数目 < 1000


第3-n行是需要合并的数组,不同的数组用回车换行分隔,数组内部用逗号分隔,最大不超过100个元素。


**输出描述**


输出一个新的数组,用逗号分隔。


#### 用例




|  |  |
| --- | --- |
| 输入 | 3 2 2,5,6,7,9,5,7 1,7,4,3,4 |
| 输出 | 2,5,6,1,7,4,7,9,5,3,4,7 |
| 说明 | 1、获得长度3和数组数目2 2、先遍历第一行,获得2,5,6 3、再遍历第二行,获得1,7,4 4、再循环回到第一行,获得7,9,5 5、再遍历第二行,获得3,4 6、再回到第一行,获得7,按顺序拼接成最终结果 |




|  |  |
| --- | --- |
| 输入 | 4 3 1,2,3,4,5,6 1,2,3 1,2,3,4 |
| 输出 | 1,2,3,4,1,2,3,1,2,3,4,5,6 |
| 说明 | 无 |




---


**题目解析**


1. 使用List 内部装入一个List类型的集合。这样就可以将所有数据装入一个List中,其结构体现为[ [],[],[],[],[] ]
2. 遍历外层的List,每次取出从一个集合中取出对应的n个数据,如果该子列表的数据被取完,那么就将其从外层List中移出。
3. 直到所有子列表都移出完成,即外层List的长度为0,那么就结束程序。



import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

//3
//2
//2,5,6,7,9,5,7
//1,7,4,3,4
public class T55 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = Integer.parseInt(sc.nextLine());
int line = Integer.parseInt(sc.nextLine());
List<List> numList = new ArrayList<List>();
for (int i = 0; i < line; i++) {
List list = new ArrayList();
Arrays.stream(sc.nextLine().split(“,”)).forEach(n -> {
list.add(Integer.parseInt(n));
});
numList.add(list);
}
List resList = new ArrayList();
while (numList.size() > 0) {
for (int i = 0; i < numList.size(); i++) {
List itemList = numList.get(i);
int count = 0;
while (count < num) {
resList.add(itemList.get(0));
itemList.remove(0);
count++;
if (itemList.size() == 0)
break;
}
if (itemList.isEmpty()) {
numList.remove(itemList);
i–;// 注意 移除后集合的大小会少一个,因此i–,再i++之后,正好是移除后的下一个
}
}
}
System.out.println(resList);
}
}


**代码运行示意图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f9a8effc38d3461e8ad7d027d9c88f3c.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/aa813a57b2ef42bbb24ea4347445b205.png)


### 56.整数对最小和


**题目描述**


给定两个整数数组array1、array2,数组元素按[升序排列]( )。


假设从array1、array2中分别取出一个元素可构成一对元素,现在需要取出k对元素,


并对取出的所有元素求和,计算和的最小值。


注意:


两对元素如果对应于array1、array2中的两个下标均相同,则视为同一对元素。


**输入描述**


输入两行数组array1、array2,每行首个数字为数组大小size(0 < size <= 100);


0 < array1[i] <= 1000


0 < array2[i] <= 1000


接下来一行为正整数k


0 < k <= array1.size() \* array2.size()


**输出描述**


满足要求的最小和


#### 用例




|  |  |
| --- | --- |
| 输入 | 3 1 1 2 3 1 2 3 2 |
| 输出 | 4 |
| 说明 | 用例中,需要取2对元素 取第一个数组第0个元素与第二个数组第0个元素组成1对元素[1,1]; 取第一个数组第1个元素与第二个数组第0个元素组成1对元素[1,1]; 求和为1+1+1+1=4,为满足要求的最小和。 |


#### 题目解析

 具体思路看代码 

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class T56 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n1 = sc.nextInt();
int nums1[] = new int[n1];
for (int i = 0; i < n1; i++)
nums1[i] = sc.nextInt();

	int n2 = sc.nextInt();
	int nums2[] = new int[n2];
	for (int i = 0; i < n2; i++)
		nums2[i] = sc.nextInt();
	int count = sc.nextInt();
	List<Integer> pointSumList = new ArrayList<Integer>();
	for (int s1 : nums1) {
		for (int s2 : nums2) {
			pointSumList.add(s1 + s2);
		}
	}
	pointSumList.sort((a, b) -> a - b);
	System.out.println(pointSumList);
	int sum = 0;
	while (count > 0) {
		count--;
		sum += pointSumList.get(count);
	}
	System.out.println(sum);
}

}


**代码运行示例**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/640678471b7a4e7184c302d41df39638.png)


### 57.乱序整数序列两数之和绝对值最小


**题目描述**


给定一个随机的整数(可能存在正整数和负整数)数组 nums,请你在该数组中找出两个数,其和的绝对值(**|nums[x]+nums[y]|**)为最小值,并返回这个两个数(按从小到大返回)以及绝对值。


每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。


**输入描述**


一个通过空格分割的有序整数序列字符串,最多1000个整数,且整数数值范围是 [-65535, 65535]。


**输出描述**


两数之和绝对值最小值


#### 用例




|  |  |
| --- | --- |
| 输入 | -1 -3 7 5 11 15 |
| 输出 | -3 5 2 |
| 说明 | 因为 |nums[0] + nums[2]| = |-3 + 5| = 2 最小,所以返回 -3 5 2。 |


**解析**


1. 使用for循环暴力组合破解
2. 将数分组 正数一组,负数一组 分组后排序  
 2.1. 若全正,则找最小的两个 若全负 则找最大的两个  
 2.2. 若正负结合,则合并两个列表 使用双指针进行求解



import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
//-1 -3 7 5 11 15
public class T57 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List positiveNums = new ArrayList();
List negativeNums = new ArrayList();
Arrays.stream(sc.nextLine().split(" “)).forEach(item -> {
int num = Integer.parseInt(item);
if (num < 0) {
negativeNums.add(num);
} else {
positiveNums.add(num);
}
});
positiveNums.sort((a, b) -> a - b);// 升序
negativeNums.sort((a, b) -> b - a);// 降序
//System.out.println(positiveNums);
//System.out.println(negativeNums);
if(positiveNums.size()==0) {
//纯负数
System.out.println(negativeNums.get(1)+” “+negativeNums.get(0)+” “+Math.abs(negativeNums.get(1)+negativeNums.get(0)));
}
if(negativeNums.size()==0) {
System.out.println(positiveNums.get(0)+” “+positiveNums.get(1)+” “+Math.abs(positiveNums.get(0)+positiveNums.get(1)));
}
if(negativeNums.size()>0&&positiveNums.size()>0) {
//组合 就得组合了 说不定负数那边前两个 正数那边前两个 亦或者 一正一负
int min=Integer.MAX_VALUE;
int minNumber=negativeNums.get(negativeNums.size()-1);
int maxNumber=positiveNums.get(positiveNums.size()-1);
if(negativeNums.size()>=2&&negativeNums.get(0)+negativeNums.get(1)<min) {
min=Math.abs(negativeNums.get(0)+negativeNums.get(1));
minNumber=negativeNums.get(1);
maxNumber=negativeNums.get(0);
}
if(positiveNums.size()>=2&&positiveNums.get(0)+positiveNums.get(1)<min) {
min=Math.abs(positiveNums.get(0)+positiveNums.get(1));
minNumber=positiveNums.get(0);
maxNumber=positiveNums.get(1);
}
//双指针
int left=0;
int right=1;
List numsList=new ArrayList();
numsList.addAll(negativeNums);
numsList.addAll(positiveNums);
while(left<numsList.size()-1) {
right=left+1;
while(right<numsList.size()) {
if(min>Math.abs(numsList.get(left)+numsList.get(right))) {
min=Math.abs(numsList.get(left)+numsList.get(right));
minNumber=numsList.get(left);
maxNumber=numsList.get(right);
}
//System.out.println(numsList.get(left)+”-“+numsList.get(right)+”-“);
right++;
}
left++;
}
System.out.println(minNumber+” “+maxNumber+” "+ min);
}
}
}


![在这里插入图片描述](https://img-blog.csdnimg.cn/1f564e4cd63b44f78e331f458a48af10.png)


### 58.检查是否存在满足条件的数字组合


**题目描述**


给定一个正整数数组,检查数组中是否存在满足规则的数字组合


规则:**A = B + 2C**


**输入描述**


第一行[输出数组]( )的元素个数。


接下来一行输出所有数组元素,用空格隔开。


**输出描述**


如果存在满足要求的数,在同一行里依次输出规则里A/B/C的取值,用空格隔开。


如果不存在,输出0。


**备注**


1. 数组长度在3-100之间。
2. 数组成员为0-65535,数组成员可以重复,但每个成员只能在结果算式中使用一次。如:数组成员为[0, 0, 1, 5],0出现2次是允许的,但结果0 = 0 + 2 \* 0是不允许的,因为算式中使用了3个0。
3. 用例保证每组数字里最多只有一组符合要求的解。


#### 用例




|  |  |
| --- | --- |
| 输入 | 4 2 7 3 0 |
| 输出 | 7 3 2 |
| 说明 | 7 = 3 + 2 \* 2 |




|  |  |
| --- | --- |
| 输入 | 3 1 1 1 |
| 输出 | 0 |
| 说明 | 找不到满足条件的组合 |


#### 题目解析


1. 需要明确的是每个数字出现的次数不大于数组中出现的次数,也就意味着每个索引只能使用一次。A=B+2C 这个A、B、C其实是可以重复的 如数组[0,0,0,1]中 是允许出现ABC分别为0,且满足条件的。
2. 使用三重for循环 强行破解
3. 使用数位规划算法来解题


**for循环强行破解**



import java.util.Scanner;

public class Y1 {
static int rawNums[]=null;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int num=Integer.parseInt(sc.nextLine());
rawNums=new int[num];
for(int i=0;i<num;i++) {
rawNums[i]=sc.nextInt();
}
for(int i=0;i<num;i++) {
for(int j=0;j<num;j++) {
for(int k=0;k<num;k++) {
if(ij||ik||k==j)continue;
if(rawNums[i]==rawNums[j]+2*rawNums[k]) {
System.out.println(rawNums[i]+" “+rawNums[j]+” “+rawNums[k]);
System.exit(0);
}
if(rawNums[i]==rawNums[k]+2*rawNums[j]) {
System.out.println(rawNums[i]+” “+rawNums[k]+” "+rawNums[j]);
System.exit(0);
}
}
}
}
System.out.println(0);
}
}


**数位DP算法进行求解**



import java.util.Scanner;

public class T58 {
static int rawNums[] = null;
static int tempNum[] = new int[3];// 存储取出的ABC

public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	int num = Integer.parseInt(sc.nextLine());
	rawNums = new int[num];
	for (int i = 0; i < num; i++) {
		rawNums[i] = sc.nextInt();
	}
	dp(0, -1, -1);
	System.out.println(0);
}

/\*\*

*
* @param p 取到哪一层
* @param first 第一层取了哪个索引
* @param sencond 第二层取了哪个索引
*/
public static void dp(int p, int first, int sencond) {
if (p == 3) {
if (tempNum[0] == tempNum[1] + tempNum[2] * 2) {
System.out.println(tempNum[0] + " " + tempNum[1] + " " + tempNum[2]);
System.exit(0);
}
return;
}
for (int i = 0; i < rawNums.length; i++) {
if (i != first && i != sencond) {
tempNum[p] = rawNums[i];
if (p == 0) {
dp(p + 1, i, sencond);
}
if (p == 1) {
dp(p + 1, first, i);
}
if (p == 2) {
dp(p + 1, first, sencond);
}
}
}
}
}


**代码运行示意图**


![在这里插入图片描述](https://img-blog.csdnimg.cn/d51bffbbd4ac4f0a942e91f5ec23e90c.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/7bf7e798b1184017b871fc09356a747b.png)


### 59.ABR 车路协同场景


**题目描述**


数轴×有两个点的序列 A={A1, A2, …, Am}和 B={B1, B2, ..., Bn}, Ai 和 Bj 均为正整数, A、 B 已经从小到大排好序, A、 B 均肯定不为空,


给定一个距离 R(正整数),列出同时满足如下条件的所有(Ai, Bj)数对


**条件:**


1. Ai <= Bj
2. Ai,Bj 距离小于等于 R,但如果 Ai 找不到 R 范围内的 Bj,则列出距它最近的 1 个 Bj,当然此种情况仍然要满足 1,


但如果仍然找不到,就丢弃 Ai。


**原型:**


[车路协同]( )场景,一条路上发生了有很多事件( A),要通过很多路测设备( B)广播给路上的车,需要给每个事件找到一个合适的路测设备去发送广播消息。


**输入描述**


按照**人易读**的格式输入一行数据,参见输入样例,其中“ [ABR]( )={, }”中的每个字符都是关键分割符,输入中无空格,其他均为任意正整数,


输入 A 和 B 已经排好序, A 和 B 的大小不超过 50,正整数范围不会超过 65535。


**输出描述**


( Ai,Bj)数对序列,排列顺序满足序列中前面的 Ax<=后面的 Ay,前面的 Bx<=后面的 By,


因为输入 A 和 B 已经排好序,所以实际上输出结果不用特意排序,排序不是考察点。


#### 用例




|  |  |
| --- | --- |
| 输入 | A={1,3,5},B={2,4,6},R=1 |
| 输出 | (1,2)(3,4)(5,6) |
| 说明 | 无 |



**解析**  
 把题目读懂就完事了,主要是对于没有b-a=r时,要取一个比之前取过的更大一点的b…逻辑不是很绕,具体看代码


**示例代码**



public class T59 {
public static void main(String[] args) {
int[] arrA = { 1, 3, 5 };
int[] arrB = { 2, 4, 7 };
int r = 1;
for (int a : arrA) {
int tempB = -1;// 上次取了哪个b
int near = -1;// 距离a近的
boolean flag = false;// 是否找到一个b和a匹配
for (int b : arrB) {
if (b - a == r && b > tempB) {
System.out.print(“(” + a + “,” + b + “)”);
tempB = b;
flag = true;
break;
}
if (b - a > r) {
near = b;
break;
}
}
if (flag == false && near != -1) {
// 没找到 那么就找一个离a 较近的 若找不到就放弃
System.out.print(“(” + a + “,” + near + “)”);
}
}
}
}


**代码运行截图**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6e66a099a3d94844a40395cd7ceeb23e.png)


### 60.AI面板识别


**题目描述**


AI识别到面板上有N(1 ≤ N ≤ 100)个指示灯,灯大小一样,任意两个之间无重叠。


由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2),


请输出先行后列排序的指示灯的编号,排序规则:


1. 每次在尚未排序的灯中挑选最高的灯作为的基准灯,
2. 找出和基准灯属于同一行所有的灯进行排序。两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差 ≤ 灯高度的一半)。




---


**输入描述**


第一行为N,表示灯的个数  
 接下来N行,每行为1个灯的坐标信息,格式为:



> 
> 编号 x1 y1 2 y2
> 
> 
> 


* 编号全局唯一
* 1 ≤ 编号 ≤ 100
* 0 ≤ x1 < x2 ≤ 1000
* 0  ≤  y1 < y2 ≤ 1000




---


**输出描述**


排序后的编号列表,编号之间以空格分隔


#### 用例




|  |  |
| --- | --- |
| 输入 | 5 1 0 0 2 2 2 6 1 8 3 3 3 2 5 4 5 5 4 7 6 4 0 4 2 6 |
| 输出 | 1 2 3 4 5 |
| 说明 |  |



**解析**


1. 这个题用例中说明图例2和3编号写反了,注意理解题目的意思
2. 给出的坐标是左上角和右下角,且排序是找所有未排序的点的最高点作为基准点,然后找到基准点那一行进行排序,例如说明中的图(编号1和3位是1行 2是1行 4和5 是一行 )
3. 请注意排序规则  
 每次在尚未排序的灯中挑选最高的灯作为的基准灯,  
 找出和基准灯属于同一行所有的灯进行排序。两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差 ≤ 灯高度的一半)


![在这里插入图片描述](https://img-blog.csdnimg.cn/3b778372a97e473084fee45661339b21.png)  
 若按照排序规则来说的画,1,2,3 属于同一行 且排序时,先行后列,则 最终排序结果为1,2,3 而**并非1,3,2**


4. 这个题可以使用List来进行灯坐标存储,然后先找出未排序的最大的,然后是找出和最大的灯处于同一行的,按x1坐标进行排序。谁小谁排在前。每次找完一行,就把找到的数据移出。
5. 例如输入  
 5  
 1 0 0 2 2  
 2 3 0 5 3  
 3 6 0 8 2  
 4 0 6 2 7  
 5 4 6 6 7  
 图形展示如下:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5cf65f80f93745b0bfb091c52f7a8d8c.png)  
 那么输出id顺序应该为 1 2 3 4 5 其中 1 2 3 为一行



import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class T60 {
static class Light {
int id, x1, y1, x2, y2;

	public Light(int id, int x1, int y1, int x2, int y2) {
		super();
		this.id = id;
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}
}

static List<Light> lightList = new ArrayList<>();

public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	int num = Integer.parseInt(sc.nextLine());
	for (int i = 0; i < num; i++) {
		String line = sc.nextLine();
		String numStrArr[] = line.split(" ");
		int id = Integer.parseInt(numStrArr[0]);
		int x1 = Integer.parseInt(numStrArr[1]);
		int y1 = Integer.parseInt(numStrArr[2]);
		int x2 = Integer.parseInt(numStrArr[3]);
		int y2 = Integer.parseInt(numStrArr[4]);
		Light light = new Light(id, x1, y1, x2, y2);
		lightList.add(light);
	}
	while (lightList.size() > 0) {
		Light maxLight = getMaxLight();

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

面试真题

Spring源码笔记

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

0 5 3
3 6 0 8 2
4 0 6 2 7
5 4 6 6 7
图形展示如下:
在这里插入图片描述
那么输出id顺序应该为 1 2 3 4 5 其中 1 2 3 为一行

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class T60 {
	static class Light {
		int id, x1, y1, x2, y2;

		public Light(int id, int x1, int y1, int x2, int y2) {
			super();
			this.id = id;
			this.x1 = x1;
			this.y1 = y1;
			this.x2 = x2;
			this.y2 = y2;
		}
	}

	static List<Light> lightList = new ArrayList<>();

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num = Integer.parseInt(sc.nextLine());
		for (int i = 0; i < num; i++) {
			String line = sc.nextLine();
			String numStrArr[] = line.split(" ");
			int id = Integer.parseInt(numStrArr[0]);
			int x1 = Integer.parseInt(numStrArr[1]);
			int y1 = Integer.parseInt(numStrArr[2]);
			int x2 = Integer.parseInt(numStrArr[3]);
			int y2 = Integer.parseInt(numStrArr[4]);
			Light light = new Light(id, x1, y1, x2, y2);
			lightList.add(light);
		}
		while (lightList.size() > 0) {
			Light maxLight = getMaxLight();


# 总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

[外链图片转存中...(img-qiKkEZwj-1715506893892)]


[外链图片转存中...(img-dySkmvAS-1715506893892)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值