小明思考

          Just a software engineer
          posts - 124, comments - 36, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          問題給定一個(gè)未排序的整數(shù)數(shù)組,求最長的連續(xù)序列的長度。要求算法的時(shí)間復(fù)雜度在O(n)
          比如對(duì)于數(shù)組[100, 4, 200, 1, 3, 2],其中最長序列為[1,2,3,4],所以應(yīng)該返回4

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

          解法思路:
          因?yàn)橐髲?fù)雜度是O(n),可以考慮使用哈希表進(jìn)行查詢。使用兩個(gè)HashMap分別記錄序列的開始值和結(jié)束值。遍歷數(shù)組,如果發(fā)現(xiàn)比該元素大1的開始值或者比改元素小1的結(jié)束值,均進(jìn)行合并工作。

          不多說了,看代碼。

          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;
              }


          評(píng)論

          # re: 最長連續(xù)序列問題[未登錄]  回復(fù)  更多評(píng)論   

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

          # re: 最長連續(xù)序列問題[未登錄]  回復(fù)  更多評(píng)論   

          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: 最長連續(xù)序列問題[未登錄]  回復(fù)  更多評(píng)論   

          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: 最長連續(xù)序列問題  回復(fù)  更多評(píng)論   

          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: 最長連續(xù)序列問題  回復(fù)  更多評(píng)論   

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

          你這個(gè)算法肯定不是,光排序就是O(nlgn)的復(fù)雜度了

          # re: 最長連續(xù)序列問題[未登錄]  回復(fù)  更多評(píng)論   

          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: 最長連續(xù)序列問題[未登錄]  回復(fù)  更多評(píng)論   

          2013-04-16 13:29 by Harry
          any way, it is an interesting problem.
          主站蜘蛛池模板: 濮阳市| 韶山市| 莱州市| 新和县| 吉林省| 垦利县| 正蓝旗| 荔波县| 巴马| 玉环县| 镇远县| 阜康市| 海盐县| 西华县| 枣强县| 浦江县| 霍林郭勒市| 莎车县| 石棉县| 改则县| 昭觉县| 宜城市| 辰溪县| 长泰县| 肥乡县| 朝阳区| 儋州市| 南丰县| 府谷县| 新邵县| 九龙城区| 定边县| 汝阳县| 景宁| 金门县| 甘孜| 永善县| 广南县| 吴江市| 武山县| 新河县|