小明思考

Just a software engineer
posts - 124, comments - 36, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

最长连续序列问题

Posted on 2013-04-12 15:58 小明 阅读(2405) 评论(7)  编辑  收藏 所属分类: 数据结构和算法
问题给定一个未排序的整数数组,求最长的连续序列的长度。要求算法的时间复杂度在O(n)
比如对于数组[100, 4, 200, 1, 3, 2],其中最长序列为[1,2,3,4],所以应该返回4

public class Solution {
     public int longestConsecutive(int[] num) {
        //write your code here
        }
}

解法思路:
因为要求复杂度是O(n),可以考虑使用哈希表进行查询。使用两个HashMap分别记录序列的开始值和结束值。遍历数组,如果发现比该元素大1的开始值或者比改元素小1的结束值,均进行合并工作。

不多说了,看代码。

private static class Sequence{
        int start;
        int end;
        int length;
    }
    
    public int longestConsecutive(int[] num) {
        int len =0;
        if(num==null || (len=num.length)<1){
            return 0;
        }
        
        Map<Integer,Sequence> start = new HashMap<Integer,Sequence>();
        Map<Integer,Sequence> end = new HashMap<Integer,Sequence>();
        int maxLength = 0;
        
        for(int i=0;i<len;++i){
            Sequence s = null;
            int v = num[i];
            if(start.containsKey(v) || end.containsKey(v)){
                continue;
            }
            if(start.containsKey(v+1)){
                s = start.remove(v+1);
                s.start = v;
                ++s.length;
                while(end.containsKey(s.start-1)){ //merge ends
                    Sequence m = end.remove(s.start-1);
                    start.remove(m.start);
                    s.start = m.start;
                    s.length += m.length;
                }
                start.put(s.start, s);
            }
            else if(end.containsKey(v-1)){
                s = end.remove(v-1);
                s.end = v;
                ++s.length;
                while(start.containsKey(s.end+1)){ //merge starts
                    Sequence m = start.remove(s.end+1);
                    end.remove(m.end);
                    s.end = m.end;
                    s.length += m.length;
                }
                end.put(s.end, s);
            }
            else{
                s = new Sequence();
                s.start = s.end = v;
                s.length = 1;
                start.put(v,s);
                end.put(v,s);
            }
            //System.out.println(i+" "+v+" seqence:"+s.start+"/"+s.end+"/"+s.length);
            if(maxLength<s.length){
                maxLength = s.length;
            }
        }
        
        return maxLength;
    }


评论

# re: 最长连续序列问题[未登录]  回复  更多评论   

2013-04-15 15:00 by Harry
I am afraid that the containsKey function is not O(1) operation.

# re: 最长连续序列问题[未登录]  回复  更多评论   

2013-04-15 15:10 by Harry
additionally, this structure was merely O(n)
for(int i=0;i<len;++i){
while(end.containsKey(s.start-1)){ //merge ends


# re: 最长连续序列问题[未登录]  回复  更多评论   

2013-04-15 15:30 by Harry
write in scala: (is it O(n) complexity?)

def maxSeq(lst: List[Int]): Int = {
val l = lst.sortWith(_ < _)
def findMax(ls: List[Int], maxLen: Int, curr: Int): Int = {
ls match {
case x :: y :: lst if x + 1 == y => findMax(y :: lst, if (maxLen > curr + 1) maxLen else curr + 1, curr + 1)
case x :: xs => findMax(xs, maxLen, 0)
case Nil => maxLen
}

}
findMax(l, 0, 0) + 1
}
def main(args: Array[String]): Unit = {
val lst = List(300, 1, 3, 2, 4, 5, 7, 9, 10, 22, 18, 6)
println(maxSeq(lst))
}

# re: 最长连续序列问题  回复  更多评论   

2013-04-15 17:21 by 小明
@Harry

Containkey of hashmap should be O(1) normally. In worst is O(n) when there are lots of hash conflicts.

# re: 最长连续序列问题  回复  更多评论   

2013-04-15 17:25 by 小明
@Harry

你这个算法肯定不是,光排序就是O(nlgn)的复杂度了

# re: 最长连续序列问题[未登录]  回复  更多评论   

2013-04-16 13:27 by Harry
you're right. the sort function already is O(nlgn)... but I wonder that there is no such a solution to the problem with O(n) complexity.

# re: 最长连续序列问题[未登录]  回复  更多评论   

2013-04-16 13:29 by Harry
any way, it is an interesting problem.

只有注册用户登录后才能发表评论。


网站导航: