一种复杂度为O(1)获取两个List差集的算法(JAVA)
2017-10-15 11:13
417 查看
一种复杂度为O(1)获取两个List差集的算法(JAVA)
1.模型图
两个List的差集为A,合集为B
![](https://img-blog.csdn.net/20171015234323869?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
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
![](https://img-blog.csdn.net/20171015235715615?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1
![](https://img-blog.csdn.net/20171016000023360?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图2
![](https://img-blog.csdn.net/20171016000336870?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图3
![](https://img-blog.csdn.net/20171016000443319?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图4
![](https://img-blog.csdn.net/20171016000810063?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图5
![](https://img-blog.csdn.net/20171016000956423?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6
![](https://img-blog.csdn.net/20171016001230622?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amllMzc5OTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图7
3.代码实现
针对500万数据进行测试所花费的时间为105ms,效果相当的好!
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,效果相当的好!
相关文章推荐
- Java 获取两个List的交集和差集,以及应用场景
- java 如何获取得到两个list中不同的数据
- python两个 list 获取交集,并集,差集的方法
- java常用算法之两个有序list的合并
- JAVA-获取两个list中相同的数据
- python两个 list 获取交集,并集,差集的方法
- 比较两个List的算法 java实现
- Pyton 获取两个 list 的差集、并集
- JAVA工具类学习-java 两个list 交集 并集 差集 去重复并集
- python两个list获取交集,并集,差集
- C# Linq获取两个List或数组的差集交集
- java 对两个list进行“交集,并集,差集,去重复并集”的操作
- C# Linq获取两个List或数组的差集交集
- Java从一个连续的自然数区间中,随机获取几个数(这几个数是固定的,一种抽奖算法及节省空间地保存结果)
- java-----求两个list的交集、并集、和差集
- JAVA获取两个List<String>中不同的数据
- java常用算法之两个有序list的合并
- C# Linq获取两个List或数组的差集交集
- 在java中,如何用最简单,效率最高的获取两个list中相同的数据
- python两个 list 获取交集,并集,差集的方法.