一种复杂度为O(1)获取两个List差集的算法(JAVA)

一种复杂度为O(1)获取两个List差集的算法(JAVA)

1.模型图

两个List的差集为A,合集为B


2.算法思路

1,首先两个指针同时指向两个list的初始位置,若如果当两个值相等时,也即图一所示,指针同时加1,变为图形2

2,当两边list的值较大的一方进行指针加1,另一方list保持不变,如图3

3,当相等时继续指针加1,如图4

4,当两边list的值较大的一方进行指针加1,另一方list保持不变,如图5

5,当两个list,其中有一个执行结束时,跳出循环,如图6

6,然后继续处理后续未结束那个list,直到另一list也结束,如图7



                                      图1

 

                                 图2                                                            

           

                                   图3

     

                                  图4                                                          


                                    图5


                                     图6


                                  图7

3.代码实现

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * @author liujie
 *
 *         两个排好序的list获取差集,并集和合集
 */
public class SortList {

	private static final long N = 5000000;

	public static void main(String[] args) {
		List<Integer> list1 = new ArrayList<Integer>();
		List<Integer> list2 = new ArrayList<Integer>();
		long t1 = System.currentTimeMillis();
		for (int i = 0; i < N; i++) {
			list1.add(i);
			list2.add(i+1000);
		}
		long t2 = System.currentTimeMillis();

		Iterator<Integer> it1 = list1.iterator();
		Iterator<Integer> it2 = list2.iterator();
		System.out.println("**********list1**************");
//		while (it1.hasNext()) {
//			System.out.println("it1.next() = " + it1.next());
//		}
		System.out.println("**********list2**************");
//		while (it2.hasNext()) {
//			System.out.println("it2.next() = " + it2.next());
//		}
		
		List<Integer> list3 = new ArrayList<Integer>();
		Collections.sort(list1);
		long t3 = System.currentTimeMillis();
		Collections.sort(list2);
		long t4 = System.currentTimeMillis();
		list3 = getASubB(list1, list2);
		long t5 = System.currentTimeMillis();
		System.out.println("**********list3**************");
		Collections.sort(list3);
		Iterator<Integer> it3 = list3.iterator();
//		while(it3.hasNext())
//		{
//			System.out.println("it3.next() = " + it3.next());
//		}
		
		System.out.println("(t2 - t1) =" + (t2 -t1));
		System.out.println("(t3 - t2) =" + (t3 -t2));
		System.out.println("(t4 - t3) =" + (t4 -t3));
		System.out.println("(t5 - t4) =" + (t5 -t4));
		
	}

	/**
	 * 两个list的差集
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	private static List<Integer> getASubB(List<Integer> a, List<Integer> b) {
		List<Integer> c = new ArrayList<Integer>();
		int i = 0;
		int j = 0;
		while(true){
			if (a.get(i).equals(b.get(j))) {
				i++;
				j++;
				if(j >= b.size())
				{
					break;
				}
				if(i >= a.size())
				{
					break;
				}
			}
			if (a.get(i).compareTo(b.get(j)) > 0) {
				c.add(b.get(j));
				j++;	
				if(j >= b.size())
				{
					break;
				}
			}
			if (a.get(i).compareTo(b.get(j)) < 0) {
				c.add(a.get(i));
				i++;
				if(i >= a.size())
				{
					break;
				}
			}

		}
		System.out.println("i = " + i + ", j = " + j);
		// 临界条件处理
		while (i < a.size()) {
			c.add(a.get(i));
			i++;
		}

		while (j < b.size()) {
			c.add(b.get(j));
			j++;
		}
		
		return c;
	}
}
4,执行结果

针对500万数据进行测试所花费的时间为105ms,效果相当的好!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章