"Coding Interview Guide" -- 数组中的最长连续序列

题目

  给定无序数组arr,返回其中最长的连续序列的长度

  举例,arr=[100,4,200,1,3,2],最长的连续序列为[1,2,3,4],所以返回4

分析

  HashMap是一种存储键值对(key-value)的数据结构,基于哈希表实现Map接口。可以使用这种数据结构来寻找最长连续序列的长度

  首先生成一个HashMap的实例map,其中key表示数组元素,value表示该元素所在连续序列的长度。从头开始遍历数组,如果元素arr[i]不在map中,则将(arr[i], 1)放入map中,代表目前arr[i]单独作为一个连续序列,然后查看map中是否有arr[i]-1,如果有,则说明arr[i]-1所在的连续序列可以和arr[i]合并,合并后记为A序列,利用map可以得到A序列的长度,记为lenA,序列的左边界元素记为leftA,右边界元素记为rightA,只在map中更新合并后的序列的相关信息,即两个边界信息和长度信息,更新成(leftA, lenA)和(rightA, lenA);再查看map中是否有arr[i]+1,如果有,说明arr[i]+1所在的连续序列可以和序列A合并,合并后记为B序列。通过map可以得到B序列的长度,记为lenB,序列B的左边界元素记为leftB,右边界元素记为rightB,只在map中更新合并后序列的相关信息,即两个序列边界信息和长度信息,更新成(leftB, lenB)和(rightB, lenB)。遍历过程中用一个全局变量max记录每次合并后,所有连续序列中长度的最大值,即为最长连续序列的长度。

  遍历过程中只需要更新合并后序列的两个边界信息和序列长度信息,因为我们判断两个序列是否可以合并,是根据这两个序列的边界信息判断的,和这两个序列的中间元素无关,所以对于这两个序列的中间元素,不用更新其value值。

 1 public int longestConsecutive(int[] arr)
 2 {
 3     if(arr == null || arr.length == 0)
 4     {
 5       return 0;
 6     }
 7 
 8     HashMap<Integer, Integer> map = new HashMap<>();
 9     int max = 1;
10 
11     for(int i = 0; i < arr.length; i++)
12     {
13         if(!map.containsKey(arr[i]))
14       {
15             map.put(arr[i], 1);
16             if(map.containsKey(arr[i]-1))         // 如果map中存在arr[i]-1,说明arr[i]可以和arr[i]-1所在的序列合并
17           {
18             max = Math.max(max, merge(map, arr[i]-1, arr[i])); 
19           }
20           if(map.containsKey(arr[i]+1))         // 如果map中存在arr[i]+1,说明arr[i]所在的序列可以和arr[i]+1所在的序列合并
21           {
22             max = Math.max(max, merge(map, arr[i], arr[i]+1));
23           }
24       }
25     }
26     return max;
27 }
28 
29 public int merge(HashMap<Integer, Integer> map, int less, int more)
30 {
31     int left = less - map.get(less) + 1;     // 合并后连续序列的左边界
32     int right = more + map.get(more) - 1;    // 合并后连续序列的右边界
33     int len = right - left + 1;              // 合并后连续序列的长度
34     map.put(left, len);                      // 更新合并后连续序列的左边界元素的value,即左边界元素所在连续序列的长度
35     map.put(right, len);                     // 更新合并后连续序列的右边界元素的value,即右边界元素所在连续序列的长度
36     return len;
37 }
38      

来源:左程云老师《程序员代码面试指南》

原文地址:https://www.cnblogs.com/OoycyoO/p/10881444.html