clojure實現最長上升子序隊列算法

4Clojure上的一道題:4Clojure 最長上升子序列算法 描述以下:算法

Given a vector of integers, find the longest consecutive sub-sequence of increasing numbers. If two sub-sequences have the same length, use the one that occurs first. An increasing sub-sequence must have a length of 2 or greater to qualify.app

例: [1 0 1 2 3 0 4 5]的最長上升子序列爲 [0 1 2 3] [5 6 1 3 2 7]的最長上升子序列爲 [5 6]oop

(defn test [coll]
;使用map存放每一個起始元素的上升隊列,key無心義,僅用於標記不一樣的隊列
(loop [flag 0
     tmp-result {flag [(first coll)]}
     index 0]
  (if (< index (- (count coll) 1))
    (let [current (nth coll index)
          next (nth coll (inc index))]
    (if (> next current)
      ;若是下一個元素大於當前元素,把下一個元素加入到當前元素的隊列中,flag就是key,保持不變
     (recur flag (assoc tmp-result flag (conj (tmp-result flag) next)) (inc index))
      ;不然說明新的隊列開始了,新建一個隊列,key爲flag+1,value爲下一個元素
     (recur (inc flag) (assoc tmp-result (inc flag) [next]) (inc index))))
  ;獲得結果以後篩選最長的隊列
  (let [tmp (vals tmp-result)]
    (loop [final (first tmp)
           s (next tmp)]
      (if (first s)
        (if (>= (count (first s)) (count final))
          (recur (first s) (next s))
          (recur final (next s)))
        ;隊列長度至少爲2
        (if (> (count final) 1)
          final
          [])))))))

另一種實現:rest

(defn test [coll]
  (let [pairs (partition 2 1 coll)
        ; 分組:first與last大小比較
        group-pairs (partition-by #(< (first %) (last %)) pairs)
        ; 保留first大於last的pair
        filter-pairs (filter #(every? (fn [pair] (< (first pair) (last pair))) %) group-pairs)
        ; 
        rise-seq (map #(concat 
                          (first %) 
                          ; 取pair的最後一個數字
                          (map last (rest %))) 
                      filter-pairs)
        candidate (reverse rise-seq)]
        (if 
          (empty? candidate)
          []
          (apply (partial max-key count) candidate))))

最終結果:code

user=> (test [5 6 1 3 2 7])
[5 6]
user=> (test [1 0 -1 3 0])
[-1 3]
user=> (test [1 0 1 2 3 0 4 5])
[0 1 2 3]
相關文章
相關標籤/搜索