❗❗❗必看:
下列题我全部都使用 Java 语言写的,并且均可以提交成功,获得Accepted 结果的. 如果代码和详解看了之后,对答案有任何疑问,都可以在评论区提出来,我都会一个一个回答.
❗❗❗感谢大家的支持,如果喜欢我的博客,关注 点赞 收藏 评论一波,非常感谢!!!
题目:和为给定数
给出若干个整数,询问其中是否有一对数的和等于给定的数。
Input
共三行:
第一行是整数n(0 < n <= 100,000),表示有n个整数。
第二行是n个整数。整数的范围是在0到10^8之间。
第三行是一个整数m(0 <= m <= 2^30),表示需要得到的和。
Output
若存在和为m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No。
样例测试
输入
4
2 5 1 4
6
输出
1 5
代码
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
//给定数的和
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] numbers = new int[n];
for(int i = 0;i<n;i++) {
numbers[i] = sc.nextInt();
}
int m = sc.nextInt();
String result = finPairWithSum(numbers,m);
System.out.println(result);
}
private static String finPairWithSum( int[] numbers, int m) {
Map<Integer,Boolean> seen = new HashMap<>();
int[] result = null;
for(int num:numbers) {
int complement = m-num;
if(seen.containsKey(complement)) {
int[] candidate = new int[] {Math.min(complement, num),Math.max(complement, num)};
if(result==null||candidate[0]<result[0]) {
result = candidate;
}
}
seen.put(num, true);
}
if(result!=null) {
return result[0]+" "+result[1];
}else {
return "No";
}
}
}
初步思路
利用哈希表存储已遍历的数字,快速查找与当前数字相加等于目标和的补数。
具体步骤
-
初始化与输入读取:
- 使用 Scanner 读取输入的整数 n 和数组 numbers 以及目标和 m。
-
遍历数组,查找符合条件的数对:
-
创建一个哈希表 seen,用于存储已遍历的数字。
-
遍历
numbers
数组中的每个数字
num
:
- 计算 complement = m - num,即需要寻找的与 num 相加等于 m 的补数。
- 检查哈希表 seen是否包含 complement
- 如果存在,则找到一个符合条件的数对 canditdate该数对中较小的数放在前面。
- 如果当前 result 为空或candidate中较小的数比 result中的较小数更小,则更新 result 为 candidate。
- 将当前数字 num 存入哈希表 seen。
-
-
输出结果:
- 如果找到符合条件的数对 result,则输出这对数。
- 如果没有找到符合条件的数对,则输出 “No”。
总结方法
使用哈希表进行查找可以显著提升查找效率,从而在线性时间内解决寻找两数之和的问题。这个方法通过一边遍历数组一边记录已经遍历过的数字,在常数时间内查找是否存在所需的补数,这样可以避免嵌套循环带来的时间复杂度问题。