求2个Integer对象 有序列表 的交集

本文介绍了一种高效的算法,用于求解两个已排序列表的交集,并通过改进减少了处理大量数据时的时间消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



public class CollectionUtils
{

/**
* 合并2个 有序列表的交集
* @param c1
* @param c2
* @return List
*/
public static List<Integer> retainOrderListAll(List<Integer>c1,List<Integer>c2 )
{
if(c1.size()<=c2.size()){//长度小的列表作为参考列表
return retain(c1,c2);
}
else{
return retain(c2,c1);
}
}

/**
* 比较前提是2个列表都是 升序排序好的...
* @param minList
* @param maxList
* @return List
*/
private static List<Integer> retain(List<Integer> minList,List<Integer> maxList){

bre1:for( Iterator<Integer> it = minList.iterator();it.hasNext(); )
{
Integer int1 = it.next(); //当前参照值
bre2:for(Iterator<Integer> it2 = maxList.iterator();it2.hasNext();)
{
Integer int2 = it2.next(); //当前比较值;

===比较2个数值的大小 根据比较的结果进行3种操作=====//
(1)如果 相等 那么就移除list2中当前值,进入list1下一轮循环
(2)如果 参照值int1 大于 比较值int2 那么删除小值int2 继续list2中的循环查找 -->(1)
(3)如果 参照值int1 小于 比较值int2 那么删除小值int1 继续list1中的循环-->(1);


//============值 匹配时==================== ;
if(int1.equals(int2)){
it2.remove();//list2中比较过的数值 直接删除...避免下次再次比较该数值;
continue bre1;//进入下一轮list1循环;
}
//=============未 匹配时=====================;
if(int1 > int2){
//参照值大于比较值时;
it2.remove();
continue;
}
//参照值小于 比较值时,说明此参照值肯定不会被匹配,直接删除 进入下一轮list1循环
if(int1 < int2){
it.remove();
continue bre1;
}
}
//=================list2为空时 list1中的所有剩余值全部移除 该判断要放在后面,以防列表被清空时,当前的it 没被移除直接进入下一次循环了;
if(maxList.size()==0){
it.remove();
continue;
}
}
return minList;
}
}


测试过
50000 条记录 和 33333条记录的两个列表 求交集时间是1800ms左右
100000条 和 66666条记录的两个列表 求交集时间是8000ms左右

因为it.remove 需要重新整理索引 所以速度耗费了很大一块

修正后:

public class CollectionUtils
{

/**
* 合并2个 求有序列表的交集
* 列表为null时候 那么就视为全集;
* @param c1
* @param c2
* @return List
*/
public static List<Integer> retainOrderListAll(List<Integer>c1,List<Integer>c2 )
{
//===========是否存在null列表对象==============
if(c1==null && c2==null){//都为null
return null;
}
else if(c1==null && c2!=null){//其中一个为null 返回另一个列表
return c2;
}
else if(c1!=null && c2 == null){
return c1;
}
//==========列表对象都不为null时======================
if(c1.size()<=c2.size()){//长度小的列表作为参考列表
return retain(c1,c2);
}
else{
return retain(c2,c1);
}
}

/**
* 比较前提是2个列表都是 升序排序好的...
* @param minList
* @param maxList
* @return List
*/
private static List<Integer> retain(List<Integer> minList,List<Integer> maxList){

// int compCount = 0;//比较次数;

List<Integer> r = new ArrayList<Integer>();

int index1 = 0;
int size1 = minList.size();

int index2 = 0;
int size2 = maxList.size();

loop1: for( ;index1 < size1;index1++){

loop2: for( ;index2 < size2;index2++ )
{
if(minList.get(index1).equals( maxList.get( index2))){
r.add( minList.get( index1));
index2++;
continue loop1;
}
if(minList.get(index1) > maxList.get( index2)){

continue;
}
if(minList.get(index1) < maxList.get( index2)){
continue loop1;
}
}
}
return r;
}

/**
* 判断列表 是否是一个空列表对象;
* 且非null;
* @param list
* @return boolean
*/
public static boolean isEmptyList(List list){
if(list!=null && list.size()==0){
return true;
}else{
return false;
}
}
}

测试后速度提高了几百倍
基本是线性复杂度 最高复杂度是 M+N
耗时在 几十ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值