我正在尝试完成此处发现的Hackerrank Maximum Element挑战:https://www.hackerrank.com/challenges/maximum-element/problem
我的解决方案产生正确的输出,但是以#17开头的最终测试用例超时。
最初,我使用了list和loop / recur来得到我的答案:
(defn get-query []
(map #(Integer/parseInt %) (clojure.string/split (read-line) #" ")))
(defn stack-stepper [query stack]
(condp = (first query)
1 (conj stack (second query))
2 (rest stack)
3 (do (println (apply max stack)) stack)))
(loop [stack '()
queries-left (Integer/parseInt (read-line))]
(if (> queries-left 0)
(recur (stack-stepper (get-query) stack) (dec queries-left))))
经过一些研究和其他渠道的反馈,我尝试了一个向量而不是一个列表,并减少而不是循环/重复,但结果是相同的。
(defn get-query []
(map #(Integer/parseInt %) (clojure.string/split (read-line) #" ")))
(defn get-queries []
(loop [queries []
queries-left (Integer/parseInt (read-line))]
(if (= queries-left 0)
queries
(recur (conj queries (get-query)) (dec queries-left)))))
(defn stack-stepper [stack query]
(condp = (first query)
1 (conj stack (second query))
2 (pop stack)
3 (do (println (apply max stack)) stack)))
(reduce stack-stepper [] (get-queries))
我还是FP和Clojure的新手,我真的很想了解我所缺少的东西。非常感谢您的时间和帮助!
答案 0 :(得分:3)
从性能的角度来看,HackerRank问题通常非常苛刻。
首先尝试的显而易见的事情是使用瞬态向量,看看是否有帮助。我试过这个:
(let [in (clojure.string/split (slurp *in*) #"\s")
tests (first in)
input-data (map #(Integer/parseInt %) (rest in))]
(loop [v (transient [])
d input-data]
(when (seq d)
(condp = (first d)
1 (recur (conj! v (second d)) (drop 2 d))
2 (recur (pop! v) (rest d))
3 (let [pv (persistent! v)] (println (apply max pv)) (recur (transient pv) (rest d)))))))
如果与您的解决方案同时失败。很显然,他们正在寻找比这更聪明的东西。
明显的瓶颈是计算当前堆栈的最大值,每次都会重新计算。我们可以将先前的最大值保存在堆栈上,并在弹出堆栈时将其恢复为当前最大值:
(defn peek! [tvec] (get tvec (dec (count tvec))))
(let [in (clojure.string/split (slurp *in*) #"\s")
tests (first in)
input-data (map #(Integer/parseInt %) (rest in))]
(loop [v (transient [])
m 0
d input-data]
(when (seq d)
(condp = (first d)
1 (let [snd (second d)
max-now (max m snd)]
(recur (conj! v {:val snd :max-prev m}) max-now (drop 2 d)))
2 (let [popped (peek! v)
max (if popped (:max-prev popped) 0)]
(recur (pop! v) max (rest d)))
3 (do
(println m)
(recur v m (rest d)))))))
这使我在排行榜上排名第一:)