diff --git a/kt/remove-nodes-from-linked-list.kt b/kt/remove-nodes-from-linked-list.kt new file mode 100644 index 0000000..41d5ded --- /dev/null +++ b/kt/remove-nodes-from-linked-list.kt @@ -0,0 +1,71 @@ +class ListNode(var `val`: Int) { + var next: ListNode? = null +} + +fun toListNode(vararg xs: Int): ListNode? { + if (xs.isEmpty()) { + return null + } + + val dummy = ListNode(0) + var node = dummy + + for (x in xs) { + val next = ListNode(x) + node.next = next + node = next + } + + return dummy.next +} + +fun linkedListEquals(head: ListNode?, xs: List): Boolean { + var node = head + for ((i, x) in xs.withIndex()) { + if (node == null) { + println("[DEBUG] $x is expected at index $i in the linked list, but is not present") + return false + } else if (node.`val` != x) { + println("[DEBUG] $x is expected at index $i in the linked list, but ${node.`val`} is present") + return false + } + + node = node.next + } + + if (node != null) { + println("[DEBUG] Linked list is longer than expected") + } + + return node == null +} + +class Solution { + fun removeNodes(head: ListNode?): ListNode? = removeNodesRec(head).first + + private fun removeNodesRec(head: ListNode?): Pair { + if (head == null) { + return head to Int.MIN_VALUE + } else if (head.next == null) { + return head to head.`val` + } + + val (next, rightMax) = removeNodesRec(head.next) + + var node = head + if (head.`val` < rightMax) { + node = next + } else { + node.next = next + } + + return node to maxOf(head.`val`, rightMax) + } +} + +fun main() { + val s = Solution() + + check(linkedListEquals(s.removeNodes(toListNode(5, 2, 13, 3, 8)), listOf(13, 8))) + check(linkedListEquals(s.removeNodes(toListNode(1, 1, 1, 1)), listOf(1, 1, 1, 1))) +}