问题描述:在给定n个数中找出两个数的和为固定值key。输入n,再输入n个数,最后输入key
输出所有的可能情况,如果没有找到输出"Not Found key. "
输入:
9
1 6 9 7 8 4 6 5 9
11
输出:5 6
5 6
4 7
在这个时候我们最常规的思路为,将此数组用两层循环嵌套逐个相加与k值作比较这个时候时间复杂度为O(n*n)
实现如下
import java.util.Scanner;
public class TowFindKey{
static void found1(int []array,int key){
int cnt= 0;
//对每一个和值与key作比较
for(int i=0;i<array.length-1;++i) {
for(int j=i+1;j<array.length;++j) {
if(array[i]+array[j]==key) {
System.out.println(array[i]+ " "+array[j]);
cnt++;
}
}
}
if(cnt==0) {
System.out.println("Not Found key.");
}
}
public static void main(String[] args) {
int n,key,k=0;
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
int []array=new int[n];
for(int i=0;i<n;++i) {
array[i]=scan.nextInt();
}
key=scan.nextInt();
scan.close();
found1(array,key);
}
}
我们可不可以换一个思路将我们的先这个无序的数组变成有序的的数组(例如用Arrays.sort()方法)(以升序为例)这个时候我们是不是就可以将我们数据的值从我们数组的两头向中间跑。使i=0,j=arrry.length-1与key作比较如果比key小i++后移,如果比key大j--向前移。如果等于输出。时间复杂度为O(n)。
代码实现如下:
import java.util.Arrays;
import java.util.Scanner;
public class TowFindKey {
static void found2(int []array,int key){
int cnt=0;
Arrays.sort(array);
//当i,j重合说明数组已经跑完
for(int i=0,j=array.length-1;j!=i;) {
if(array[i]+array[j]==key) {
cnt++;
System.out.println(array[i]+" "+array[j]);
i++;
}
else if(array[i]+array[j]>key) {
j--;//j向前移
}
else {
i++;//i向后移
}
}
if(cnt==0) {
System.out.println("Not Found key.");
}
}
public static void main(String[] args) {
int n,key,k=0;
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
int []array=new int[n];
for(int i=0;i<n;++i) {
array[i]=scan.nextInt();
}
key=scan.nextInt();
scan.close();
found2(array,key);
}
}
大家看到上面的代码后,相信已经有一些大佬已经看出来了前面程序的bug了,当其中可能重复值的时候将会少给我们输出几组解:
我本人对此代码的改善如下:
import java.util.Arrays;
import java.util.Scanner;
public class TowFindKey {
static void found3(int []array,int key){
int k=0,g = -1,cnt=0;
Arrays.sort(array);
for(int i=0,j=array.length-1;j!=i;) {
if(array[i]+array[j]==key) {
cnt++;
System.out.println(array[i]+" "+array[j]+" ");
//g为当j重复值且它还未被处理
if(array[j]==array[j-1]&&g==-1) {
g=i;
}
i++;
}
else if(array[i]+array[j]>key) {
//当重复的前面的i跑完,这个时候j也有重复将i拉回来然后使j跑
if(g!=-1) {
i=g;
g=-1;
}
j--;
}
else {
i++;
}
}
if(cnt==0) {
System.out.println("Not Found key. ");
}
}
public static void main(String[] args) {
int n,key,k=0;
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
int []array=new int[n];
for(int i=0;i<n;++i) {
array[i]=scan.nextInt();
}
key=scan.nextInt();
scan.close();
found3(array,key);
}
相信很多大佬有更好的解决方法欢迎大家提出,本人的水平不高,希望大家多多指教。