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:
elem=3, l1=[1,2,3,4], l2=[5,6,3,8]
False
elem=6, l1=[5,6,7,8], l2=[1,2,6,4]
True
elem=6, l1=[5,7,6,8], l2=[1,6,2,4]
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]
Example 3: elem=6, l1=[5,6,7,8], l2=[1,2,6,4]
Example 4: elem=6, l1=[5,7,6,8], l2=[1,6,2,4]
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.
Key takeaways¶
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.
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.
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.