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]