我正在https://www.hackerrank.com/challenges/ctci-merge-sort上进行hackerrank
挑战Merge Sort: Counting Inversions
。
这是通过所有测试用例的Python2代码。
def mergeSortInversions(arr):
if len(arr) == 1:
return arr, 0
else:
a = arr[:(len(arr)/2)]
b = arr[(len(arr)/2):]
a, ai = mergeSortInversions(a)
b, bi = mergeSortInversions(b)
c = []
i = 0
j = 0
inversions = 0 + ai + bi
while i < len(a) and j < len(b):
if a[i] <= b[j]:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
inversions += (len(a)-i)
c += a[i:]
c += b[j:]
return c, inversions
# Complete the countInversions function below.
def countInversions(arr):
_, ret = mergeSortInversions(arr)
return ret
我正在尝试在Clojure中实现相同的逻辑,但是由于timeout
,我无法通过所有测试用例。这是代码:
(defn merge-sort-inversion [sq]
(let [len (count sq)]
(if (= 1 len)
[sq 0]
(let [mid (quot len 2)
[a ainv] (merge-sort-inversion (take mid sq))
[b binv] (merge-sort-inversion (drop mid sq))
lena (count a)
lenb (count b)]
(loop [c []
i 0
j 0
inversions (+ ainv binv)]
(if (and (< i lena)
(< j lenb))
(let [ai (nth a i)
bj (nth b j)]
(if (<= ai bj)
(recur (conj c ai) (inc i) j inversions)
(recur (conj c bj) i (inc j) (+ inversions (- (count a) i)))))
[(concat c (drop i a) (drop j b)) inversions]))))))
(defn countInversions [v]
(second (merge-sort-inversion v)))
我已经使用Clojure解决了之前的一些时间紧迫性问题,因此我认为使用Clojure这样做没有问题。我相信可以使用Clojure解决此问题,并且我的Clojure代码中肯定有一些效率不高的东西,但是我无法弄清楚哪里。
我更新了Clojure代码,但在某些测试用例上仍然超时。
感谢,但我不知道如何制作subvec
transient
。
(defn merge-sort-inversion [v]
(let [len (count v)]
(cond
(= 1 len) [v 0]
:else
(let [mid (quot len 2)
[a ainv] (merge-sort-inversion (subvec v 0 mid))
[b binv] (merge-sort-inversion (subvec v mid))
lena (count a)
lenb (count b)]
(loop [c []
i 0
j 0
inversions (+ ainv binv)]
(if (and (< i lena)
(< j lenb))
(let [ai (get a i)
bj (get b j)]
(if (<= ai bj)
(recur (conj c ai) (inc i) j inversions)
(recur (conj c bj) i (inc j) (+ inversions (- (count a) i)))))
[(-> c
(into (drop i a))
(into (drop j b))) inversions]))))))