Facebook Pixel

3062. Winner of the Linked List Game 🔒

Problem Description

You have a linked list with an even number of nodes. The nodes are indexed starting from 0, where:

  • Nodes at even indices (0, 2, 4, ...) contain even integers
  • Nodes at odd indices (1, 3, 5, ...) contain odd integers

The list is divided into pairs of consecutive nodes:

  • Nodes at indices 0 and 1 form the first pair
  • Nodes at indices 2 and 3 form the second pair
  • And so on...

For each pair, you need to compare the values:

  • If the odd-indexed node (second node in the pair) has a higher value, the "Odd" team gets a point
  • If the even-indexed node (first node in the pair) has a higher value, the "Even" team gets a point

Your task is to determine which team wins by returning:

  • "Odd" if the Odd team has more points
  • "Even" if the Even team has more points
  • "Tie" if both teams have equal points

For example, given the list [2,5,4,7,20,5]:

  • Pair (2,5): Since 5 > 2, Odd team gets 1 point
  • Pair (4,7): Since 7 > 4, Odd team gets 1 point
  • Pair (20,5): Since 20 > 5, Even team gets 1 point
  • Final score: Odd team has 2 points, Even team has 1 point, so return "Odd"

The solution traverses the linked list in steps of two nodes, comparing each pair and keeping track of the scores. After processing all pairs, it compares the final scores to determine the winner.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem is essentially asking us to compare pairs of consecutive nodes and keep score. Since we're dealing with a linked list where every two consecutive nodes form a pair, the natural approach is to traverse the list two nodes at a time.

The key insight is that we don't need to track node indices explicitly. Since the list has an even length and we're told that even-indexed nodes contain even values while odd-indexed nodes contain odd values, we can simply process the list in chunks of two nodes. The first node we encounter in each chunk is always at an even index, and the second is at an odd index.

For scoring, we need two counters - one for the "Odd" team and one for the "Even" team. As we process each pair:

  • If the first node's value is less than the second node's value (a < b), the odd-indexed node wins, so we increment the odd counter
  • If the first node's value is greater than the second node's value (a > b), the even-indexed node wins, so we increment the even counter

The elegant part of the solution is using boolean expressions directly: odd += a < b and even += a > b. In Python, True evaluates to 1 and False evaluates to 0, so these expressions naturally increment the counters only when the respective condition is met.

After traversing all pairs, we simply compare the two scores to determine the winner. This straightforward simulation approach works because we're just following the rules of the game exactly as described - no complex transformations or algorithms needed.

Learn more about Linked List patterns.

Solution Approach

The solution uses a simple simulation approach by traversing the linked list and processing pairs of nodes sequentially.

Implementation Steps:

  1. Initialize counters: Create two variables odd and even, both set to 0, to track the scores for each team.

  2. Traverse the list in pairs: Use a while loop that continues as long as head is not null. In each iteration:

    • Extract the value of the current node: a = head.val
    • Extract the value of the next node: b = head.next.val
    • These two nodes form a pair where a is at an even index and b is at an odd index
  3. Update scores based on comparison:

    • odd += a < b: If the odd-indexed node (b) is greater than the even-indexed node (a), increment the odd team's score
    • even += a > b: If the even-indexed node (a) is greater than the odd-indexed node (b), increment the even team's score
    • Note: Python treats True as 1 and False as 0, so these boolean expressions directly add 1 or 0 to the counters
  4. Move to the next pair: Advance the pointer by two nodes using head = head.next.next to reach the start of the next pair.

  5. Determine the winner: After processing all pairs, compare the final scores:

    • If odd > even, return "Odd"
    • If odd < even, return "Even"
    • If scores are equal, return "Tie"

Time Complexity: O(n) where n is the number of nodes in the linked list, as we visit each node exactly once.

Space Complexity: O(1) as we only use two integer variables to track scores, regardless of the input size.

The beauty of this solution lies in its simplicity - it directly simulates the game rules without any unnecessary complexity, making the code both efficient and easy to understand.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a small example with the linked list: [6, 3, 10, 1]

Initial Setup:

  • odd = 0 (score for odd team)
  • even = 0 (score for even team)
  • head points to the first node (value 6)

First Iteration:

  • Current pair: nodes at indices 0 and 1
  • a = head.val = 6 (even index, even value)
  • b = head.next.val = 3 (odd index, odd value)
  • Compare: Is 6 < 3? No, so odd += False (odd remains 0)
  • Compare: Is 6 > 3? Yes, so even += True (even becomes 1)
  • Move forward: head = head.next.next (now points to node with value 10)
  • Scores: odd = 0, even = 1

Second Iteration:

  • Current pair: nodes at indices 2 and 3
  • a = head.val = 10 (even index, even value)
  • b = head.next.val = 1 (odd index, odd value)
  • Compare: Is 10 < 1? No, so odd += False (odd remains 0)
  • Compare: Is 10 > 1? Yes, so even += True (even becomes 2)
  • Move forward: head = head.next.next (now becomes null)
  • Scores: odd = 0, even = 2

Determine Winner:

  • Final scores: odd = 0, even = 2
  • Since even > odd, return "Even"

The Even team wins with 2 points to 0, having won both pair comparisons (6 > 3 and 10 > 1).

Solution Implementation

1# Definition for singly-linked list.
2# class ListNode:
3#     def __init__(self, val=0, next=None):
4#         self.val = val
5#         self.next = next
6
7from typing import Optional
8
9class Solution:
10    def gameResult(self, head: Optional[ListNode]) -> str:
11        """
12        Determines the winner of a game based on pairs of consecutive nodes.
13      
14        The linked list contains pairs of values. For each pair:
15        - If first value < second value, odd team gets a point
16        - If first value > second value, even team gets a point
17      
18        Args:
19            head: The head of the linked list containing game values
20          
21        Returns:
22            "Odd" if odd team wins, "Even" if even team wins, "Tie" if scores are equal
23        """
24        # Initialize counters for odd and even team scores
25        odd_score = 0
26        even_score = 0
27      
28        # Process pairs of nodes
29        while head:
30            # Get values from current pair
31            first_value = head.val
32            second_value = head.next.val
33          
34            # Award points based on comparison
35            # Odd team gets a point if first value is less than second
36            odd_score += first_value < second_value
37            # Even team gets a point if first value is greater than second
38            even_score += first_value > second_value
39          
40            # Move to the next pair (skip 2 nodes)
41            head = head.next.next
42      
43        # Determine and return the winner
44        if odd_score > even_score:
45            return "Odd"
46        if odd_score < even_score:
47            return "Even"
48        return "Tie"
49
1/**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 *     int val;
5 *     ListNode next;
6 *     ListNode() {}
7 *     ListNode(int val) { this.val = val; }
8 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11class Solution {
12    /**
13     * Determines the winner of a game based on comparing adjacent pairs of nodes in a linked list.
14     * Compares nodes at positions (0,1), (2,3), (4,5), etc.
15     * 
16     * @param head The head of the linked list containing an even number of nodes
17     * @return "Odd" if odd-positioned nodes win more comparisons, 
18     *         "Even" if even-positioned nodes win more comparisons,
19     *         "Tie" if both win the same number of comparisons
20     */
21    public String gameResult(ListNode head) {
22        // Counter for odd-positioned nodes winning (when even-positioned node has larger value)
23        int oddWins = 0;
24        // Counter for even-positioned nodes winning (when odd-positioned node has larger value)
25        int evenWins = 0;
26      
27        // Traverse the linked list in pairs
28        ListNode current = head;
29        while (current != null && current.next != null) {
30            // Get values of the current pair
31            int oddPositionValue = current.val;        // Node at odd position (0, 2, 4, ...)
32            int evenPositionValue = current.next.val;  // Node at even position (1, 3, 5, ...)
33          
34            // Count wins based on comparison
35            if (oddPositionValue < evenPositionValue) {
36                oddWins++;  // Odd team wins when even position has larger value
37            } else if (oddPositionValue > evenPositionValue) {
38                evenWins++; // Even team wins when odd position has larger value
39            }
40          
41            // Move to the next pair
42            current = current.next.next;
43        }
44      
45        // Determine and return the winner
46        if (oddWins > evenWins) {
47            return "Odd";
48        } else if (oddWins < evenWins) {
49            return "Even";
50        } else {
51            return "Tie";
52        }
53    }
54}
55
1/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     ListNode *next;
6 *     ListNode() : val(0), next(nullptr) {}
7 *     ListNode(int x) : val(x), next(nullptr) {}
8 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
9 * };
10 */
11class Solution {
12public:
13    /**
14     * Determines the winner of a game based on paired values in a linked list.
15     * Pairs are formed by consecutive nodes (1st-2nd, 3rd-4th, etc.)
16     * 
17     * @param head - pointer to the head of the linked list
18     * @return "Odd" if odd-positioned nodes win more pairs,
19     *         "Even" if even-positioned nodes win more pairs,
20     *         "Tie" if both win equal number of pairs
21     */
22    string gameResult(ListNode* head) {
23        int oddWins = 0;   // Count of pairs where odd-positioned node wins
24        int evenWins = 0;  // Count of pairs where even-positioned node wins
25      
26        // Iterate through the list in pairs
27        while (head != nullptr) {
28            // Get values from the current pair
29            int oddValue = head->val;           // Value at odd position (1st, 3rd, 5th...)
30            int evenValue = head->next->val;    // Value at even position (2nd, 4th, 6th...)
31          
32            // Compare the pair and update win counters
33            if (oddValue < evenValue) {
34                oddWins++;   // Odd position wins when its value is smaller
35            } else if (oddValue > evenValue) {
36                evenWins++;  // Even position wins when odd's value is larger
37            }
38            // If values are equal, neither wins (no counter is incremented)
39          
40            // Move to the next pair (skip two nodes)
41            head = head->next->next;
42        }
43      
44        // Determine and return the winner
45        if (oddWins > evenWins) {
46            return "Odd";
47        } else if (oddWins < evenWins) {
48            return "Even";
49        } else {
50            return "Tie";
51        }
52    }
53};
54
1/**
2 * Definition for singly-linked list.
3 * class ListNode {
4 *     val: number
5 *     next: ListNode | null
6 *     constructor(val?: number, next?: ListNode | null) {
7 *         this.val = (val===undefined ? 0 : val)
8 *         this.next = (next===undefined ? null : next)
9 *     }
10 * }
11 */
12
13/**
14 * Determines the winner of a game played on a linked list.
15 * The list contains pairs of values where odd-indexed nodes compete against even-indexed nodes.
16 * 
17 * @param head - The head of the linked list containing game values
18 * @returns 'Odd' if odd-indexed nodes win more, 'Even' if even-indexed nodes win more, 'Tie' if equal
19 */
20function gameResult(head: ListNode | null): string {
21    // Initialize counters for odd and even wins
22    let oddWins: number = 0;
23    let evenWins: number = 0;
24  
25    // Traverse the linked list in pairs
26    while (head !== null && head.next !== null) {
27        // Get the values of the current pair
28        const oddNodeValue: number = head.val;
29        const evenNodeValue: number = head.next.val;
30      
31        // Count wins based on value comparison
32        if (oddNodeValue < evenNodeValue) {
33            oddWins++;
34        } else if (oddNodeValue > evenNodeValue) {
35            evenWins++;
36        }
37      
38        // Move to the next pair of nodes
39        head = head.next.next;
40    }
41  
42    // Determine and return the winner
43    if (oddWins > evenWins) {
44        return 'Odd';
45    } else if (oddWins < evenWins) {
46        return 'Even';
47    } else {
48        return 'Tie';
49    }
50}
51

Time and Space Complexity

Time Complexity: O(n), where n is the length of the linked list. The algorithm traverses the linked list once, visiting each node exactly once. In each iteration of the while loop, we process two nodes (the current node and its next node) and then move forward by two positions with head = head.next.next. Since we visit all n nodes in the list exactly once, the time complexity is linear.

Space Complexity: O(1). The algorithm uses only a constant amount of extra space regardless of the input size. We only maintain two integer variables (odd and even) to keep track of the scores, plus a few temporary variables (a and b) to store node values. These variables do not grow with the size of the input linked list, resulting in constant space complexity.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Null Pointer Exception When Accessing head.next.val

The most critical pitfall in this solution is assuming that head.next always exists when processing pairs. If someone modifies the code or uses it in a different context, accessing head.next.val without checking if head.next is null will cause a runtime error.

Problem Example:

# This will crash if head.next is None
second_value = head.next.val  # AttributeError if head.next is None

Solution: Add a safety check before accessing the next node:

while head and head.next:  # Check both head and head.next
    first_value = head.val
    second_value = head.next.val
    # ... rest of the logic

2. Incorrect Handling of Odd Number of Nodes

While the problem states the list has an even number of nodes, defensive programming suggests handling edge cases. If the list accidentally has an odd number of nodes, the current implementation will crash.

Solution: Either validate the input or handle incomplete pairs:

def gameResult(self, head: Optional[ListNode]) -> str:
    odd_score = 0
    even_score = 0
  
    # Handle edge case of empty list
    if not head:
        return "Tie"
  
    while head and head.next:
        first_value = head.val
        second_value = head.next.val
      
        odd_score += first_value < second_value
        even_score += first_value > second_value
      
        head = head.next.next
  
    # Optional: Check if there's a leftover node (odd length list)
    if head:
        # Could handle this case or raise an exception
        pass
  
    if odd_score > even_score:
        return "Odd"
    if odd_score < even_score:
        return "Even"
    return "Tie"

3. Confusion About Index-Based Team Names

The problem states that nodes at even indices contain even integers and nodes at odd indices contain odd integers, but the team names ("Odd" and "Even") refer to the index positions, not the values themselves. This can lead to confusion when reading or modifying the code.

Solution: Use clearer variable names and add comments:

# More descriptive variable names
odd_index_team_score = 0   # Score for nodes at odd indices (1, 3, 5...)
even_index_team_score = 0  # Score for nodes at even indices (0, 2, 4...)

# Or use position-based naming
second_position_wins = 0  # When second node in pair wins
first_position_wins = 0   # When first node in pair wins

4. Integer Overflow in Score Counters

While unlikely in Python (which handles arbitrary precision integers), in other languages with fixed-size integers, very long lists could cause integer overflow in the score counters.

Solution for other languages: Use appropriate data types or implement overflow checking:

# In languages with fixed integers, consider using long/int64
# or checking for overflow conditions
if odd_score == sys.maxsize:  # Example overflow check
    # Handle overflow case
    pass
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which data structure is used in a depth first search?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More