小明思考

          Just a software engineer
          posts - 124, comments - 36, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          最長連續序列問題

          Posted on 2013-04-12 15:58 小明 閱讀(2420) 評論(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.
          主站蜘蛛池模板: 武隆县| 望奎县| 斗六市| 谷城县| 电白县| 同江市| 彭州市| 汾西县| 德州市| 崇左市| 甘肃省| 明星| 金坛市| 集安市| 铜鼓县| 南乐县| 灌阳县| 内江市| 蓬溪县| 泰和县| 阳泉市| 龙胜| 巴南区| 民权县| 宁城县| 岐山县| 郓城县| 佛冈县| 凌海市| 朝阳县| 来宾市| 陈巴尔虎旗| 富阳市| 建昌县| 舞阳县| 新乡县| 河东区| 正镶白旗| 乐清市| 兰西县| 山东省|