我正在hackerrank上尝试以下问题:
https://www.hackerrank.com/challenges/counting-valleys
但是不幸的是,我下面的Clojure代码在许多测试用例上都超时了,我不知道是什么使它如此低效。请宽容。我总共只有2个小时的clojure经验。
declare
v_sql varchar2(10000);
l_table_name varchar2(40) := 'arch_tbl_'
|| TO_CHAR( add_months(sysdate,-1),'MON');
BEGIN
v_sql := 'select .. into ....... from ' || l_table_name || ' .... ';
execute immediate v_sql;
commit;
END;
使用5分钟并通过所有测试用例的相同逻辑的简单易用的python实现:
(require '[clojure.string :as str])
; Complete the countingValleys function below.
(defn countingValleys [n s]
(do
(def running 0)
(defn counter [elem]
(do
(cond
(= elem "D") (def running (+ running 1))
(= elem "U")(def running (- running 1))
)
running
)
)
(def valley-num 0)
(defn valley-count [a b]
(do
(if (and (= a "U") (= b 0))
(def valley-num (+ valley-num 1)))
)
)
(def heights (for [elem s] (counter elem)))
(doseq [[i j] (map vector s heights)]
(valley-count i j))
valley-num
)
)
(def fptr (get (System/getenv) "OUTPUT_PATH"))
(def n (Integer/parseInt (clojure.string/trim (read-line))))
(def s (read-line))
(def result (countingValleys n (str/split s #"")))
(spit fptr (str result "\n") :append true)
答案 0 :(得分:3)
所以我知道了。效率低下是这样的:
(doseq [[i j] (map vector s heights)]
(valley-count i j))
可以替换为:
(doall (map valley-count s heights))
,然后所有测试通过。
答案 1 :(得分:0)
代码缓慢是其问题中最少的。您应该使用的工具是
我喜欢您的基本算法:计算 up 运动将您带到海平面的情况。
我们可以这样惯用地表达它:
(defn countingValleys [n s]
(let [counter {\D 1, \U -1}
heights (reductions + (map counter s))
s-heights (map vector s heights)
valley-num (count (filter #{[\U 0]} s-heights))]
valley-num))
...或使用->>
线程宏...
(defn countingValleys [_ s]
(->> s
(map {\D 1, \U -1})
(reductions +)
(map vector s)
(filter #{[\U 0]})
(count)))
这些比您更清晰,更快。
似乎您和HackerRank实际上正在使用ClojureScript。将"U"
用作字符串的元素在Clojure中不起作用:您必须使用字符\U
。
答案 2 :(得分:-1)
Those of us who are JavaScript(Node JS) developers, my solution here works perfectly
// Complete the countingValleys function below.
function countingValleys(n, s) {
const min = 2;
const max = 1000000;
let valleys = 0;
let isInValley;
s = (typeof s === 'string') ? s.split('') : s;
if (s.length >= min && s.length <= max &&
n === parseInt(n, 0) &&
n >= min &&
n <= max &&
n === s.length) {
s.map(steps => ((steps === "U") ? 1 : -1))
.reduce((prev, next) => {
if (prev < 0 && !isInValley) {
isInValley = true;
}
if ((prev + next) === 0 && isInValley) {
valleys++;
isInValley = false;
}
return prev + next;
});
}
return valleys;
}