Problem

Given a linked list, rearrange the node values such that they appear in alternating low -> high -> low -> high … form.

Examples

Example 1

1
2
3
Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 3 -> 2 -> 5 -> 4
Explanation: The values alternate between low and high: 1 < 3 > 2 < 5 > 4

Example 2

1
2
3
Input: 5 -> 4 -> 3 -> 2 -> 1
Output: 4 -> 5 -> 2 -> 3 -> 1
Explanation: After rearranging: 4 < 5 > 2 < 3 > 1

Example 3

1
2
3
Input: 1
Output: 1
Explanation: Single node remains unchanged

Example 4

1
2
3
Input: 3 -> 1
Output: 1 -> 3
Explanation: Ensure first position has smaller value: 1 < 3

Method 1 - In-Place Value Swapping

Intuition

We can achieve the wiggle pattern by traversing the linked list and ensuring that at even positions (0, 2, 4…) we have smaller values than the next position, and at odd positions (1, 3, 5…) we have larger values than the next position. If this condition is violated, we simply swap the values.

Approach

  1. Start from the head of the linked list
  2. Traverse the list with a position counter
  3. For even positions (i % 2 == 0): ensure current value < next value
  4. For odd positions (i % 2 == 1): ensure current value > next value
  5. If the condition is violated, swap the current and next node values
  6. Continue until we reach the end of the list
  7. Return the modified linked list

Code

C++

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public:
    ListNode* wiggleSort(ListNode* head) {
        if (!head || !head->next) return head;
        
        ListNode* curr = head;
        int pos = 0;
        
        while (curr && curr->next) {
            if (pos % 2 == 0) {
                // Even position: should be smaller than next
                if (curr->val > curr->next->val) {
                    swap(curr->val, curr->next->val);
                }
            } else {
                // Odd position: should be larger than next
                if (curr->val < curr->next->val) {
                    swap(curr->val, curr->next->val);
                }
            }
            curr = curr->next;
            pos++;
        }
        
        return head;
    }
};

Go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func wiggleSort(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    
    curr := head
    pos := 0
    
    for curr != nil && curr.Next != nil {
        if pos%2 == 0 {
            // Even position: should be smaller than next
            if curr.Val > curr.Next.Val {
                curr.Val, curr.Next.Val = curr.Next.Val, curr.Val
            }
        } else {
            // Odd position: should be larger than next
            if curr.Val < curr.Next.Val {
                curr.Val, curr.Next.Val = curr.Next.Val, curr.Val
            }
        }
        curr = curr.Next
        pos++
    }
    
    return head
}

Java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
    public ListNode wiggleSort(ListNode head) {
        if (head == null || head.next == null) return head;
        
        ListNode curr = head;
        int pos = 0;
        
        while (curr != null && curr.next != null) {
            if (pos % 2 == 0) {
                // Even position: should be smaller than next
                if (curr.val > curr.next.val) {
                    int temp = curr.val;
                    curr.val = curr.next.val;
                    curr.next.val = temp;
                }
            } else {
                // Odd position: should be larger than next
                if (curr.val < curr.next.val) {
                    int temp = curr.val;
                    curr.val = curr.next.val;
                    curr.next.val = temp;
                }
            }
            curr = curr.next;
            pos++;
        }
        
        return head;
    }
}

Kotlin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
    fun wiggleSort(head: ListNode?): ListNode? {
        if (head?.next == null) return head
        
        var curr = head
        var pos = 0
        
        while (curr?.next != null) {
            if (pos % 2 == 0) {
                // Even position: should be smaller than next
                if (curr.`val` > curr.next!!.`val`) {
                    val temp = curr.`val`
                    curr.`val` = curr.next!!.`val`
                    curr.next!!.`val` = temp
                }
            } else {
                // Odd position: should be larger than next
                if (curr.`val` < curr.next!!.`val`) {
                    val temp = curr.`val`
                    curr.`val` = curr.next!!.`val`
                    curr.next!!.`val` = temp
                }
            }
            curr = curr.next
            pos++
        }
        
        return head
    }
}

Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
    def wiggleSort(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        
        curr = head
        pos = 0
        
        while curr and curr.next:
            if pos % 2 == 0:
                # Even position: should be smaller than next
                if curr.val > curr.next.val:
                    curr.val, curr.next.val = curr.next.val, curr.val
            else:
                # Odd position: should be larger than next
                if curr.val < curr.next.val:
                    curr.val, curr.next.val = curr.next.val, curr.val
            
            curr = curr.next
            pos += 1
        
        return head

Rust

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
impl Solution {
    pub fn wiggle_sort(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        if head.is_none() || head.as_ref().unwrap().next.is_none() {
            return head;
        }
        
        let mut head = head;
        let mut curr = head.as_mut();
        let mut pos = 0;
        
        while let Some(node) = curr {
            if let Some(next_node) = &mut node.next {
                if pos % 2 == 0 {
                    // Even position: should be smaller than next
                    if node.val > next_node.val {
                        let temp = node.val;
                        node.val = next_node.val;
                        next_node.val = temp;
                    }
                } else {
                    // Odd position: should be larger than next
                    if node.val < next_node.val {
                        let temp = node.val;
                        node.val = next_node.val;
                        next_node.val = temp;
                    }
                }
                curr = node.next.as_mut();
                pos += 1;
            } else {
                break;
            }
        }
        
        head
    }
}

TypeScript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
    wiggleSort(head: ListNode | null): ListNode | null {
        if (!head || !head.next) return head;
        
        let curr: ListNode | null = head;
        let pos = 0;
        
        while (curr && curr.next) {
            if (pos % 2 === 0) {
                // Even position: should be smaller than next
                if (curr.val > curr.next.val) {
                    [curr.val, curr.next.val] = [curr.next.val, curr.val];
                }
            } else {
                // Odd position: should be larger than next
                if (curr.val < curr.next.val) {
                    [curr.val, curr.next.val] = [curr.next.val, curr.val];
                }
            }
            curr = curr.next;
            pos++;
        }
        
        return head;
    }
}

Complexity

  • ⏰ Time complexity: O(n), where n is the number of nodes in the linked list. We traverse the list exactly once
  • 🧺 Space complexity: O(1), as we only use a constant amount of extra space for variables

Method 2 - Sort and Rearrange

Intuition (Sort and Rearrange)

Another approach is to first extract all values from the linked list, sort them, and then rearrange them in a wiggle pattern. We place smaller values at even positions and larger values at odd positions alternately.

Approach (Sort and Rearrange)

  1. Traverse the linked list and collect all values in an array
  2. Sort the array of values
  3. Create the wiggle pattern by:
    • Placing values at even indices of sorted array at positions 0, 2, 4…
    • Placing values at odd indices of sorted array at positions 1, 3, 5…
  4. Update the linked list nodes with the rearranged values
  5. Return the modified linked list

Code (Sort and Rearrange)

C++ (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Solution {
public:
    ListNode* wiggleSort(ListNode* head) {
        if (!head || !head->next) return head;
        
        vector<int> vals;
        ListNode* curr = head;
        
        // Collect all values
        while (curr) {
            vals.push_back(curr->val);
            curr = curr->next;
        }
        
        // Sort values
        sort(vals.begin(), vals.end());
        
        // Rearrange in wiggle pattern
        vector<int> ans(vals.size());
        int left = 0, right = 1;
        
        for (int i = 0; i < vals.size(); i++) {
            if (i % 2 == 0) {
                ans[left] = vals[i];
                left += 2;
            } else {
                ans[right] = vals[i];
                right += 2;
            }
        }
        
        // Update linked list
        curr = head;
        for (int val : ans) {
            curr->val = val;
            curr = curr->next;
        }
        
        return head;
    }
};

Go (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
func wiggleSort(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    
    var vals []int
    curr := head
    
    // Collect all values
    for curr != nil {
        vals = append(vals, curr.Val)
        curr = curr.Next
    }
    
    // Sort values
    sort.Ints(vals)
    
    // Rearrange in wiggle pattern
    ans := make([]int, len(vals))
    left, right := 0, 1
    
    for i, val := range vals {
        if i%2 == 0 {
            ans[left] = val
            left += 2
        } else {
            ans[right] = val
            right += 2
        }
    }
    
    // Update linked list
    curr = head
    for _, val := range ans {
        curr.Val = val
        curr = curr.Next
    }
    
    return head
}

Java (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
    public ListNode wiggleSort(ListNode head) {
        if (head == null || head.next == null) return head;
        
        List<Integer> vals = new ArrayList<>();
        ListNode curr = head;
        
        // Collect all values
        while (curr != null) {
            vals.add(curr.val);
            curr = curr.next;
        }
        
        // Sort values
        Collections.sort(vals);
        
        // Rearrange in wiggle pattern
        int[] ans = new int[vals.size()];
        int left = 0, right = 1;
        
        for (int i = 0; i < vals.size(); i++) {
            if (i % 2 == 0) {
                ans[left] = vals.get(i);
                left += 2;
            } else {
                ans[right] = vals.get(i);
                right += 2;
            }
        }
        
        // Update linked list
        curr = head;
        for (int val : ans) {
            curr.val = val;
            curr = curr.next;
        }
        
        return head;
    }
}

Kotlin (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Solution {
    fun wiggleSort(head: ListNode?): ListNode? {
        if (head?.next == null) return head
        
        val vals = mutableListOf<Int>()
        var curr = head
        
        // Collect all values
        while (curr != null) {
            vals.add(curr.`val`)
            curr = curr.next
        }
        
        // Sort values
        vals.sort()
        
        // Rearrange in wiggle pattern
        val ans = IntArray(vals.size)
        var left = 0
        var right = 1
        
        for (i in vals.indices) {
            if (i % 2 == 0) {
                ans[left] = vals[i]
                left += 2
            } else {
                ans[right] = vals[i]
                right += 2
            }
        }
        
        // Update linked list
        curr = head
        for (value in ans) {
            curr!!.`val` = value
            curr = curr.next
        }
        
        return head
    }
}

Python (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution:
    def wiggleSort(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        
        vals = []
        curr = head
        
        # Collect all values
        while curr:
            vals.append(curr.val)
            curr = curr.next
        
        # Sort values
        vals.sort()
        
        # Rearrange in wiggle pattern
        ans = [0] * len(vals)
        left, right = 0, 1
        
        for i, val in enumerate(vals):
            if i % 2 == 0:
                ans[left] = val
                left += 2
            else:
                ans[right] = val
                right += 2
        
        # Update linked list
        curr = head
        for val in ans:
            curr.val = val
            curr = curr.next
        
        return head

Rust (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
impl Solution {
    pub fn wiggle_sort(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        if head.is_none() || head.as_ref().unwrap().next.is_none() {
            return head;
        }
        
        let mut vals = Vec::new();
        let mut curr = &head;
        
        // Collect all values
        while let Some(node) = curr {
            vals.push(node.val);
            curr = &node.next;
        }
        
        // Sort values
        vals.sort();
        
        // Rearrange in wiggle pattern
        let mut ans = vec![0; vals.len()];
        let mut left = 0;
        let mut right = 1;
        
        for (i, &val) in vals.iter().enumerate() {
            if i % 2 == 0 {
                ans[left] = val;
                left += 2;
            } else {
                ans[right] = val;
                right += 2;
            }
        }
        
        // Update linked list
        let mut head = head;
        let mut curr = head.as_mut();
        for &val in &ans {
            if let Some(node) = curr {
                node.val = val;
                curr = node.next.as_mut();
            }
        }
        
        head
    }
}

TypeScript (Sort and Rearrange)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
    wiggleSort(head: ListNode | null): ListNode | null {
        if (!head || !head.next) return head;
        
        const vals: number[] = [];
        let curr: ListNode | null = head;
        
        // Collect all values
        while (curr) {
            vals.push(curr.val);
            curr = curr.next;
        }
        
        // Sort values
        vals.sort((a, b) => a - b);
        
        // Rearrange in wiggle pattern
        const ans: number[] = new Array(vals.length);
        let left = 0, right = 1;
        
        for (let i = 0; i < vals.length; i++) {
            if (i % 2 === 0) {
                ans[left] = vals[i];
                left += 2;
            } else {
                ans[right] = vals[i];
                right += 2;
            }
        }
        
        // Update linked list
        curr = head;
        for (const val of ans) {
            curr!.val = val;
            curr = curr!.next;
        }
        
        return head;
    }
}

Complexity (Sort and Rearrange)

  • ⏰ Time complexity: O(n log n), where n is the number of nodes. The sorting step dominates the time complexity
  • 🧺 Space complexity: O(n), for storing the values in arrays during the rearrangement process