LeetCode Entry

2487. Remove Nodes From Linked List

06.05.2024 medium 2024 kotlin rust

Make a Linked List non-increasing list

2487. Remove Nodes From Linked List medium blog post substack youtube 2024-05-06_09-06.webp

Join me on Telegram

https://t.me/leetcode_daily_unstoppable/594

Problem TLDR

Make a Linked List non-increasing #medium #linked_list

Intuition

The trivial way to solve it is to use a monotonic stack technique: remove from the stack all lesser nodes and always add the current. However, there is a clever O(1) memory solution: just reverse the Linked List and iterate from the tail.

Approach

Let’s save some lines of code just for the fun of it: can you use a single extra variable?

Complexity

  • Time complexity: \(O(n)\)

  • Space complexity: \(O(1)\)

Code


    fun removeNodes(head: ListNode?): ListNode? {
        var m = head
        while (head?.next != null) {
            val next = head?.next?.next
            head?.next?.next = m
            m = head?.next
            head?.next = next
        }
        while (m != null) {
            val next = if (m == head) null else m.next
            if (m.`val` >= (head?.next?.`val` ?: 0)) {
                if (m == head) return head
                m.next = head?.next
                head?.next = m
            }
            m = next
        }
        return head?.next
    }


    pub fn remove_nodes(mut head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        let (mut curr, mut prev) = (head, None);
        while let Some(mut curr_box) = curr {
            let next = curr_box.next;
            curr_box.next = prev;
            prev = Some(curr_box);
            curr = next;
        }
        while let Some(mut prev_box) = prev {
            let next = prev_box.next;
            if prev_box.val >= curr.as_ref().map_or(0, |curr| curr.val) {
                prev_box.next = curr;
                curr = Some(prev_box);
            }
            prev = next
        }
        curr
    }