java判断集合中有没有_Java面试题(判断集合中是否有两个数的和等于某个给定整数)...

首先是参考思路:

解法1

解题步骤:

1.        对数组S进行归并排序。

2.        构造数组S’={z : z=x-y, y∈S},并排序。由于S已经有序,构造与排序可一并完成。

3.        删除S中重复的元素使仅保留一个,对S’进行同样的操作。

4.        合并S和S’,并保证合并后有序,这里可以使用归并排序的思想。

5.        如果在合并后的数组中存在连续两个相同的元素,并且这种元素的个数大于1,那么有解。

设想在合并后的数组中存在连续两个w,则w分别属于S和S’,那么S中存在y使得w=x-y,即x=y+w。因此,S中元素w和y的和为x。

步骤1的运行时间为Θ(n lg n),其余步骤运行时间为Θ(n),因此总的时间代价为Θ(n lg n)。

解法2:

对S排个序O(nlgn),然后用两个指针p1,p2分别指向头尾,

if(p1+p2 == x)

return true;

else if(p1 + p2 > x)

p2--;

else

p1++;

直到2指针相遇,如果没有找到,返回false

解法3

如果x不大的话.

申请x大小的数组byte t[x],memset 0.

遍历下集合S,对于小于x的数i将t[i]=1; 这是0(N);

然后对数组t[x]遍历. 循环查找i对应的t[x-i]是否为1. 这是O(X)

相比较三种解题思路,首先第三种局限较大,没有前两种实现实用。第二种实现指针的方式一般适用于C/C++解题。第一种是一个很好的想法,所以我实现了第一种的java解法。下面是实现代码

import java.util.Arrays;

import java.util.Set;

import java.util.TreeSet;

public class TestSet {

public static void main(String[] args) {

int X = 30; //给定整数

int[] S = {2,9,7,11,45,13,18,16,20,22,25,26,27,30}; // 原始集合

Arrays.sort(S); //数组排序

int length = S.length;

int[] S1 = new int[length];

for (int i = 0 ; i < S.length; i++) {

S1[i] = X - S[i];

}

System.out.println(Arrays.toString(S));

Arrays.sort(S1);

System.out.println(Arrays.toString(S1));

int[] SS = delNum(S); //数组去重

int[] SS1 = delNum(S1);

int[] Test = new int[SS.length + SS1.length]; //结果数组

System.arraycopy(SS,0,Test,0,SS.length);

System.arraycopy(SS1,0,Test,SS.length,SS1.length);

Arrays.sort(Test);

System.out.println(Arrays.toString(Test));

int result = 0 ;

for(int i = 0 ;i< Test.length-1; i++){

if(Test[i] == Test[i+1]){

result ++;

}

}

if(result == 0){

System.out.println(" false" );

}else{

System.out.println(" ture " + result);

}

}

private static int[] delNum(int[] s) {

Set set = new TreeSet(); //Set 集合实现去重。

for (int i : s) {

set.add(i);

}

int j = 0;

int[] SS = new int[set.size()];

for (Integer i : set) {

SS[j++] = i;

}

System.out.println(Arrays.toString(SS));

return SS;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值