class Solution { public int longestConsecutive(int[] nums) { //这一题我们可以使用图的并查集算法来解决,首先要使用图的算法,先得抽象出图的节点和图的边,在这一题中图的节点是每一个数字,图的边是每一个大小相邻的节点 //首先的根据nums构建出一个并查集的根节点集,本根节点包含的节点数量,以及需要创建一个set来以O(1)的时间查找每一个元素 Map<Integer,Integer> fathers = new HashMap<>(); Map<Integer,Integer> counts = new HashMap<>(); Set<Integer> set = new HashSet<>(); for(int num : nums){ fathers.put(num,num); counts.put(num,1); set.add(num); } //查早集合中的每一个元素,看集合中是否由它相邻的元素加入到并查集中 for(int num : nums){ if(set.contains(num + 1)){ union(fathers,counts,num,num + 1); } } //最后遍历并查集所存储的元素个数,最大的哪一个就是我们要找的答案 int result = 0; for(int count : counts.keySet()){ result = Math.max(counts.get(count),result); } return result; } //查找根节点 private int findRoot(Map<Integer,Integer> fathers,int i){ //如果并节点的父节点不是自己,继续查找器父节点的父节点 if(fathers.get(i) != i){ fathers.put(i,findRoot(fathers,fathers.get(i))); } return fathers.get(i); } //联合并查集 private void union(Map<Integer,Integer> fathers,Map<Integer,Integer> counts,int i,int j){ //首先查找i和j的根节点 int rooti = findRoot(fathers,i); int rootj = findRoot(fathers,j); //如果根节点不相同需要联合 if(rooti != rootj){ fathers.put(rooti,rootj); counts.put(rootj,counts.get(rooti) + counts.get(rootj)); } } }