Skip to content

Instantly share code, notes, and snippets.

@boraseoksoon
Last active September 15, 2022 21:04
Show Gist options
  • Save boraseoksoon/eb6beab76d76d3bb7b1cde4e0777b011 to your computer and use it in GitHub Desktop.
Save boraseoksoon/eb6beab76d76d3bb7b1cde4e0777b011 to your computer and use it in GitHub Desktop.
Invert binary in Clojure
;; invert binary tree: https://leetcode.com/problems/invert-binary-tree/
;; Given the root of a binary tree, invert the tree, and return its root.
;; Input: root = [4,2,7,1,3,6,9]
;; Output: [4,7,2,9,6,3,1]
;; Input: root = [2,1,3]
;; Output: [2,3,1]
;; Input: root = []
;; Output: []
;; Constraints:
;; The number of nodes in the tree is in the range [0, 100] .
;; -100 <= Node.val <= 100
;; example:
;; when input is [4 2 7 1 3 6 9]
;;
;; 4
;; 2 7
;; 1 3 6 9
;; output should be: [4 7 2 9 6 3 1]
;;
;; 4
;; 7 2
;; 9 6 3 1
(def tree [4 2 7 1 3 6 9])
(invert tree) ;; (4 7 2 9 6 3 1)
tree ;; [4 2 7 1 3 6 9]
(defn invert
[tree
& {:keys [level subtree last-index]
:or {level 1 subtree []}}]
(defn recur-split-half [vector]
(cond
(<= (count vector) 1) (apply list vector)
(= (count vector) 2) (apply list (reverse vector))
:else
(let [half (or (split-at (/ (count vector) 2) vector) [])
first (or (nth half 0) [])
second (or (nth half 1) [])]
[(recur-split-half (vec second))
(recur-split-half (vec first))])))
(let
[log2 #(/ (Math/log %1) (Math/log 2))
exponent #(Math/pow %1 %2)
power (Math/ceil (log2 (count tree)))
trailing-nil (take (exponent 2 power) (repeat nil))
remove-trailing-nil #(reverse (drop-while nil? (reverse %1)))
tree (if (> level 1)
tree
(into tree trailing-nil))]
(cond
(not (vector? tree)) (throw (Error. "a tree must be a vector"))
(or (empty? tree)
(= (count tree) 1)) (apply list tree)
:else
(let [power (dec level)
from (or last-index 0)
to (+ from (exponent 2 power))]
(cond
(> to (count tree)) (recur-split-half subtree)
:else
(remove-trailing-nil
(flatten [(if (<= (count subtree) 1)
subtree
(recur-split-half subtree))
(invert tree
:level (inc level)
:subtree (subvec tree from to)
:last-index to)])))))))
(invert [4 2 7 1 3 6 9])
;; (4 7 2 9 6 3 1)
(invert [1 2])
;; (1 nil 2)
(invert [1 2 3 4])
;; (1 3 2 nil nil nil 4)
(invert [4 2 7 1 3 6 9 11 33 66 99 111 333 666 999])
;; (4 7 2 9 6 3 1 999 666 333 111 99 66 33 11)
@boraseoksoon
Copy link
Author

boraseoksoon commented Sep 12, 2022

Technically, it is different from the leet code requirement
where they require a mutable version of inverting binary tree
while this inverting binary tree attempts immutable version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment