Skip to content

S1Q3 · Check If Element is Present in Opposite Halves

⚡ Quick Reference

Function: is_present_in_opposite_halves(elem, l1: list, l2: list) -> bool

Core idea: split each list at the midpoint, check if elem is in the first half of one and the second half of the other - or vice versa.

def is_present_in_opposite_halves(elem, l1: list, l2: list):
    mid1, mid2 = len(l1) // 2, len(l2) // 2
    in_l1_first  = elem in l1[:mid1]
    in_l1_second = elem in l1[mid1:]
    in_l2_first  = elem in l2[:mid2]
    in_l2_second = elem in l2[mid2:]
    return (in_l1_first and in_l2_second) or (in_l1_second and in_l2_first)

Key rules: - Both lists have even lengths - midpoint = len // 2 - First half: lst[:mid], second half: lst[mid:] - Two valid cases: (l1 first ∧ l2 second) OR (l1 second ∧ l2 first)


Problem Statement

Problem

Write a function is_present_in_opposite_halves(elem, l1, l2) that returns True if elem appears in the first half of one list and the second half of the other.

Examples:

Input
elem=3, l1=[1,2,3,4], l2=[5,6,3,8]
Output
False
Input
elem=6, l1=[5,6,7,8], l2=[1,2,6,4]
Output
True
Input
elem=6, l1=[5,7,6,8], l2=[1,6,2,4]
Output
True

Understanding the problem

For a list of length n (even), split at n // 2:

l1 = [1, 2, 3, 4]   →  first half: [1, 2]   second half: [3, 4]
l2 = [5, 6, 3, 8]   →  first half: [5, 6]   second half: [3, 8]

Two cases return True:

Case A:  elem in l1 first half  AND elem in l2 second half
Case B:  elem in l1 second half AND elem in l2 first half

Both same half → False. Not present in either → False.


Tracing all examples

Example 1: elem=3, l1=[1,2,3,4], l2=[5,6,3,8]

l1 first=[1,2], l1 second=[3,4] → 3 in second half of l1
l2 first=[5,6], l2 second=[3,8] → 3 in second half of l2
Both same half (second) → False ✓

Example 2: elem=7, l1=[1,2,3,4], l2=[5,6,3,8]

7 not in l1, 7 not in l2 → False ✓

Example 3: elem=6, l1=[5,6,7,8], l2=[1,2,6,4]

l1 first=[5,6] → 6 in first half of l1
l2 second=[6,4] → 6 in second half of l2
Case A → True ✓

Example 4: elem=6, l1=[5,7,6,8], l2=[1,6,2,4]

l1 second=[6,8] → 6 in second half of l1
l2 first=[1,6]  → 6 in first half of l2
Case B → True ✓


Solution approaches

def is_present_in_opposite_halves(elem, l1: list, l2: list):
    mid1, mid2 = len(l1) // 2, len(l2) // 2
    in_l1_first  = elem in l1[:mid1]
    in_l1_second = elem in l1[mid1:]
    in_l2_first  = elem in l2[:mid2]
    in_l2_second = elem in l2[mid2:]
    return (in_l1_first and in_l2_second) or (in_l1_second and in_l2_first)
def is_present_in_opposite_halves(elem, l1: list, l2: list):
    # Split each list into halves
    mid1 = len(l1) // 2
    mid2 = len(l2) // 2

    l1_first  = l1[:mid1]
    l1_second = l1[mid1:]
    l2_first  = l2[:mid2]
    l2_second = l2[mid2:]

    # Case A: elem in first half of l1 and second half of l2
    case_a = (elem in l1_first) and (elem in l2_second)

    # Case B: elem in second half of l1 and first half of l2
    case_b = (elem in l1_second) and (elem in l2_first)

    return case_a or case_b
def is_present_in_opposite_halves(elem, l1: list, l2: list):
    mid1, mid2 = len(l1) // 2, len(l2) // 2
    # True if elem is in first half of l1 (not second)
    l1_in_first = (elem in l1[:mid1])
    l2_in_first = (elem in l2[:mid2])
    # If l1_in_first XOR l2_in_first → opposite halves
    # But only if elem appears in at least one of each list
    in_l1 = elem in l1
    in_l2 = elem in l2
    return in_l1 and in_l2 and (l1_in_first != l2_in_first)

If elem is in both lists, check if their "in-first-half" status differs. l1_in_first != l2_in_first is True exactly when they're in opposite halves. Concise but requires the element to be in both lists.

def is_present_in_opposite_halves(elem, l1: list, l2: list):
    half = lambda lst: lst[:len(lst)//2]
    in_first  = lambda e, lst: e in half(lst)
    in_second = lambda e, lst: e in lst[len(lst)//2:]
    return (
        (in_first(elem, l1) and in_second(elem, l2)) or
        (in_second(elem, l1) and in_first(elem, l2))
    )

Key takeaways

01

Split at len // 2

For even-length lists, mid = len(lst) // 2 gives the exact midpoint. lst[:mid] is the first half and lst[mid:] is the second - no overlap, no gap.

02

Two valid cases - use OR

Both (A: l1-first ∧ l2-second) and (B: l1-second ∧ l2-first) return True. Connect them with or. The same-half case naturally falls through as False.

03

The XOR trick: l1_in_first != l2_in_first

If elem is present in both lists, checking whether their "is-in-first-half" flags differ is equivalent to checking opposite halves. True != False and False != True are both True - exactly the two valid cases.