如何检查列表是否是另一个列表的子集

时间:2015-04-25 07:55:51

标签: java linked-list subset

list1:[1,2,3,4,5]
list2:[1,2,3]

如何检查list2是否是list1的子集?我尝试了containsAll(),但只要列表2中的元素存在于list1中,它就会成立。 我想要与标准相同的顺序而不仅仅是元素。

5 个答案:

答案 0 :(得分:8)

使用此:

boolean contains(List<?> list, List<?> sublist) {
    return Collections.indexOfSubList(list, sublist) != -1;
}

http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#indexOfSubList(java.util.List,%20java.util.List)

答案 1 :(得分:0)

这是算法

1)迭代第二个列表

2)检查元素是否包含在第一个列表中

如果没有返回false

如果是,请使用indexOf()

从第一个列表中获取该元素的索引

3)现在迭代检查下一个元素是否等于list1(lastMatchedIndexFromList1 ++)

如果返回false

如果是,则重复步骤3并在迭代结束时返回true

答案 2 :(得分:0)

我对此实施有点好奇所以这是我的解决方案:

public static void main(String[] args) {

    List<Integer> list1 = new ArrayList<>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list1.add(4);
    list1.add(5);

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

    list2.add(1);
    list2.add(2);
    list2.add(3);


    boolean isOrderedSublist = true;

    for (int i = 0; i < list2.size(); i++) {

        if(list1.get(i) != (int) list2.get(i)) {
            isOrderedSublist = false;
            break;
        }
    }

    System.out.println("Is ordered: " + isOrderedSublist);
}

}

答案 3 :(得分:0)

迭代list2以检查list1中是否存在每个元素。最简单的方法是使用indexOf进行检查操作,它返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1。每个检查操作时间复杂度为O(n),因为在最坏的情况下它必须迭代整个列表。

如果订购了list1,我们可以使用BinarySearch将检查操作性能提高到O(lgn)时间复杂度。

示例代码:

List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> list2 = new ArrayList<>(Arrays.asList(1, 2, 5));

boolean contains = true;
int l2 = list2.size();
int currIndex = -1;
for(int j=0;j<l2;j++) {
    int e2 = list2.get(j);
    int i1 = list1.indexOf(e2);
    if(i1 == -1) {
        contains = false;
        break;
    }
    if(i1 > currIndex) {
        currIndex = i1;
    }
}
System.out.println(contains);

时间复杂度为O(n * m)nlist1的大小,mlist2的大小。

但是,最有效的方法是不使用indexOf方法进行检查。由于需要出现顺序,因此无需在每个检查操作中迭代整个list1。只是从最后一个检查点索引做检查!

示例代码:

boolean contains = true;
int l1 = list1.size(), l2 = list2.size();
int currIndex = 0;
int i;
for(int j=0;j<l2;j++) {
    int e2 = list2.get(j);
    for(i=currIndex;i<l1;i++) {
        if(e2 == list1.get(i)) {
           break;
        }
    }
    if(i == l1) {
        contains = false;
        break;
    }
    currIndex++;
}
System.out.println(contains);

list1list2都只迭代​​一次,时间复杂度为O(n + m)

答案 4 :(得分:0)

我尝试使用下面的代码来查找顺序中的元素

import java.util.List;
import java.util.ArrayList;
class OrderArray {
  public static void main(String [] args) {
    List listSource = new ArrayList();
    for(int i =1; i <=5; i++) {
        listSource.add(i);
    }
    List target = new ArrayList();
    target.add(2);
    target.add(3);
    boolean isMatched = true;
    int [] indexArray = new int[target.size()];
    for(int i = 0; i< target.size(); i ++) {
        indexArray[i] = listSource.indexOf(target.get(i));
        if ( i !=0 ) {
            if ((indexArray[i] - indexArray[i-1]) != 1) {
                isMatched = false;
                break;
            }
        }
    }
    System.out.println("isMatched:"+isMatched);
  }
}