■ Basic Python
Interview Prep: Arrays, Strings, Math & Builtins
SECTION 1 — Arrays & Lists
Q1. Count the frequency of each element in a list
Code:
def count_freq(num):
freq = {}
for n in num:
freq[n] = [Link](n, 0) + 1
return freq
print(count_freq([1, 1, 2, 2, 3, 3])) # {1:2, 2:2, 3:2}
Explain: Iterate through each element using a dictionary. [Link](n, 0) returns the current count or 0 if not found,
then add 1. O(n) time and O(n) space.
Follow-ups:
• What is the time complexity?
• Can you use Counter from collections instead?
• How would you find the most frequent element?
■ Tip: Say: 'I prefer [Link]() over checking if key exists — it's cleaner.'
Q2. Find the least frequent element
Code:
def least_freq(num):
freq = {}
for n in num:
freq[n] = [Link](n, 0) + 1
return min(freq, key=[Link])
print(least_freq([1,2,3,2,3,1,2,2,2])) # 1
Explain: Same frequency dictionary, but use min() with key=[Link] to get the key with the lowest value.
Follow-ups:
• What does key=[Link] mean?
• What if multiple elements have the same frequency?
• Can you do this in one line?
Q3. Find first repeating element
Code:
def first_rep(num):
seen = set()
for n in num:
if n in seen:
return n
[Link](n)
return None
print(first_rep([1, 2, 3, 4, 1])) # 1
Explain: Use a set to track elements already visited. Sets have O(1) lookup. The first element found that's already
in the set is the first duplicate.
Follow-ups:
• Why set instead of list?
• What if there's no duplicate?
• What's the time and space complexity?
Q4. Find second largest element
Code:
def sec_large(num):
largest = second = float('-inf')
for n in num:
if n > largest:
second = largest
largest = n
elif largest > n > second:
second = n
return second if second != float('-inf') else None
print(sec_large([10, 2, 7, 3])) # 7
Explain: Maintain two variables — largest and second. When a new largest is found, the old largest becomes
second. O(n) single pass — better than sorting O(n log n).
Follow-ups:
• Why not just sort and take index -2?
• Handle duplicates — what if input is [5,5,5]?
• What is float('-inf') and why use it?
■ Tip: Mention the O(n) vs O(n log n) trade-off — interviewers love this.
Q5. Two Sum — find indices of two numbers that add to target
Code:
num = [1, 2, 3, 4]
target = 7
for i in range(len(num)):
for j in range(i+1, len(num)):
if num[i] + num[j] == target:
print(i, j) # 2, 3
Explain: Brute force O(n²) approach — check every pair. Can also mention the optimized O(n) approach using a
hashmap to store complements.
Follow-ups:
• What is the O(n) approach using a dictionary?
• What if the array is sorted — can you use two pointers?
• What if there are multiple valid pairs?
Q6. Move all zeros to the end (keep non-zero order)
Code:
def move_zero(nums):
nonzero = [x for x in nums if x != 0]
zeros = [0] * (len(nums) - len(nonzero))
return nonzero + zeros
print(move_zero([1, 0, 4, 5, 0, 2])) # [1, 4, 5, 2, 0, 0]
Explain: Separate non-zero elements into one list, count the zeros, and concatenate. Preserves relative order.
O(n) time, O(n) space.
Follow-ups:
• Can you do it in-place without extra space?
• What happens if all elements are zero?
• Why did you separate into two lists?
Q7. Find missing number in a sequence 1 to N
Code:
num = [1, 2, 4, 5, 6, 7]
n = 7
pred = n * (n + 1) // 2
act = sum(num)
missing = pred - act
print(missing) # 3
Explain: The sum formula for 1 to N is n*(n+1)/2. Subtract the actual sum to find the gap. O(n) — no sorting or
hashing needed.
Follow-ups:
• What if there are two missing numbers?
• What is the formula for sum of 1 to N?
• Can you do this without using sum()?
Q8. Remove duplicates and keep only unique elements
Code:
num = [1, 2, 3, 4, 5, 1, 2, 3, 4]
unique = []
for i in num:
if i not in unique:
[Link](i)
print(unique) # [1, 2, 3, 4, 5]
Explain: Build a new list, only appending if not already there. Note: searching a list is O(n), so this is O(n²). Faster
approach uses a set, but sets don't preserve order.
Follow-ups:
• What's the fastest way? (seen = set(), check in seen)
• Does your solution preserve order?
• What if you need sorted unique elements?
Q9. Find common elements between two lists
Code:
a = [1, 2, 3, 4, 7, 8]
b = [1, 3, 5, 6]
common = [i for i in a if i in b]
print(common) # [1, 3]
Explain: Iterate through list A and check if each element exists in B. For large lists, converting B to a set first
makes the lookup O(1) instead of O(n).
Follow-ups:
• What's the set-based approach?
• What about duplicates in the result?
• How is this different from set intersection?
Q10. Find duplicates in a list
Code:
s = [1, 2, 2, 2, 2, 3, 3]
dup = []
seen = []
for i in s:
if i in seen:
if i not in dup:
[Link](i)
else:
[Link](i)
print(dup) # [2, 3]
Explain: Maintain two lists — one for seen elements and one for confirmed duplicates. Only add to dup once to
avoid repeated duplicates in the result.
Follow-ups:
• Can you do this with a frequency dictionary instead?
• What is the time complexity?
• How would you count how many times each value is duplicated?
Q11. Filter even / odd numbers from a list
Code:
num = [1, 2, 2, 3, 4]
even = [i for i in num if i % 2 == 0]
print(even) # [2, 2, 4]
Explain: Simple filter using list comprehension. Modulo 2 gives 0 for even numbers. Can also use Python's filter()
with a lambda for a functional approach.
Follow-ups:
• What's the lambda/filter version?
• How would you separate into two lists — even and odd?
Q12. Square all elements in a list
Code:
num = [1, 2, 3, 4, 5]
squares = [i*i for i in num]
print(squares) # [1, 4, 9, 16, 25]
Explain: List comprehension applies the transformation to each element. Equivalent to using map(lambda x: x**2,
num).
Follow-ups:
• What's the map() equivalent?
• What is list comprehension and when is it preferred?
Q13. Rotate an array by k positions
Code:
s = [1, 2, 3, 4, 5]
k = 2
res = s[k:] + s[:k]
print(res) # [3, 4, 5, 1, 2]
Explain: Python slicing makes this elegant. s[k:] is everything from index k onwards, s[:k] is the first k elements.
Concatenating puts the tail first, then the head.
Follow-ups:
• What if k > len(s)?
• Can you do left rotation vs right rotation?
• What's the in-place approach?
Q14. Merge two sorted lists into one sorted list
Code:
list1 = [1, 3, 4, 6]
list2 = [2, 3, 8, 9]
merged = []
i, j = 0, 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
[Link](list1[i]); i += 1
else:
[Link](list2[j]); j += 1
[Link](list1[i:])
[Link](list2[j:])
print(merged) # [1, 2, 3, 3, 4, 6, 8, 9]
Explain: Classic two-pointer merge. Compare the front of each list and take the smaller one. After one list is
exhausted, append the remainder. O(n+m).
Follow-ups:
• Why extend() at the end?
• What if the lists are not sorted?
• This is the key step in Merge Sort — do you know Merge Sort?
Q15. Separate positives and negatives, then sort
Code:
num = [-1, 2, -2, 3, -4, 4]
pos = [i for i in num if i >= 0]
neg = [i for i in num if i < 0]
print(sorted(neg + pos)) # [-4, -2, -1, 2, 3, 4]
Explain: Split into two lists using comprehensions, then sort the combined result. This pattern is useful in partition
problems.
Follow-ups:
• What's the time complexity of sorted()?
• How would you do this in-place?
SECTION 2 — String Manipulation
Q16. Reverse a string
Code:
s = 'aathi'
print(s[::-1]) # 'ihtaa'
# Manual approach:
result = ""
for i in s:
result = i + result
print(result)
Explain: Python's slice s[::-1] reverses any sequence. Can also build it manually by prepending each character to
the front of the result string.
Follow-ups:
• What does [::-1] mean exactly?
• Can you reverse in-place? (Strings are immutable in Python — you can't)
• How would you reverse a list in-place?
Q17. Check if a string is a palindrome
Code:
s = 'gag'
if s[::-1] == s:
print('palindrome')
else:
print('no')
Explain: Reverse the string using slicing and compare to original. Since strings are immutable, this creates a new
string — clean and O(n).
Follow-ups:
• How would you check ignoring case and spaces? (hint: [Link]().replace(' ',''))
• Check if a number is a palindrome?
• What is the two-pointer approach?
Q18. Check if two strings are anagrams
Code:
s1 = 'listen'
s2 = 'silent'
if sorted(s1) == sorted(s2):
print('anagram')
else:
print('no')
Explain: Anagrams have the same characters in different order. Sorting both and comparing is clean — O(n log n).
The O(n) approach uses a frequency dictionary.
Follow-ups:
• What's the O(n) frequency dictionary approach?
• Are 'aab' and 'aba' anagrams? Yes.
• Handle case-insensitive anagrams?
Q19. Count vowels in a string
Code:
s = 'umayaambiga'
count = 0
for i in s:
if i in 'aeiouAEIOU':
count += 1
print(count)
Explain: Check each character against the vowel string. Using 'in' on a string is O(k) where k is the length of
vowels string — effectively O(1) since it's fixed at 10.
Follow-ups:
• Count consonants as well?
• Use sum() and a generator instead?
• Handle uppercase vowels?
Q20. Find the longest word in a sentence
Code:
sentence = 'Python programming is a great skill'
words = [Link]()
longest = max(words, key=len)
print(longest) # 'Analytics'
# Manual approach:
largest = words[0]
for word in words:
if len(word) > len(largest):
largest = word
print(largest)
Explain: split() breaks the sentence on whitespace. max() with key=len finds the longest word. Manual loop
version proves understanding of the logic.
Follow-ups:
• What if two words have the same length?
• How would you find the shortest word?
• Count words in a sentence?
Q21. Find first non-repeating character
Code:
s = 'aabbcdde'
freq = {}
for ch in s:
freq[ch] = [Link](ch, 0) + 1
for ch in s:
if freq[ch] == 1:
print(ch) # c
break
Explain: Two-pass approach: first pass builds the frequency map, second pass finds the first character with count
1 while preserving order.
Follow-ups:
• Why two passes instead of one?
• What if all characters repeat?
• Find the last non-repeating character?
Q22. Check if string is a rotation of another
Code:
s1 = 'abcde'
s2 = 'cdeab'
if len(s1) == len(s2) and s2 in (s1 + s1):
print('rotation')
Explain: Key insight: if s2 is a rotation of s1, then s2 will always appear as a substring of s1+s1. This is a classic
trick worth remembering.
Follow-ups:
• Why does s1+s1 work?
• Which built-in does 'in' use under the hood?
• What is the time complexity?
■ Tip: This is a top interview trick — mention it confidently!
Q23. Reverse the words in a sentence
Code:
s = 'aathi is a poor man'
words = [Link]()
result = ' '.join(reversed(words))
print(result) # 'man poor a is aathi'
Explain: split() gives a list of words. reversed() reverses the list. join() reassembles with spaces.
Follow-ups:
• What is the difference between reversed() and [::-1]?
• Can you do it without split()?
• Reverse each word but keep order?
Q24. Count uppercase and lowercase characters
Code:
s = 'AAAaaaBBaCCe'
lower = sum(1 for i in s if [Link]())
upper = sum(1 for i in s if [Link]())
print(lower, upper)
Explain: isupper() and islower() are built-in string methods. Using sum() with a generator is Pythonic and concise.
Follow-ups:
• What about digits and special characters?
• Convert all to uppercase/lowercase?
SECTION 3 — Math & Number Problems
Q25. Fibonacci series (first N numbers)
Code:
n = 8
a, b = 0, 1
for i in range(n):
a, b = b, a + b
print(a, end=' ')
# 1 1 2 3 5 8 13 21
Explain: Use two variables — a and b. The tuple assignment a, b = b, a+b updates both simultaneously. O(n) time
and O(1) space.
Follow-ups:
• What is the recursive approach?
• What is memoization / dynamic programming for Fibonacci?
• What is the 10th Fibonacci number?
Q26. Factorial of a number
Code:
num = 5
fact = 1
for i in range(1, num + 1):
fact = fact * i
print(fact) # 120
Explain: Iterative multiplication from 1 to n. range(1, n+1) is inclusive of n. Recursive approach: return 1 if n<=1
else n * factorial(n-1).
Follow-ups:
• What is the recursive approach?
• Factorial of 0? (Answer: 1 by definition)
• Handle large numbers in Python? (Python ints handle big numbers natively)
Q27. Check if a number is prime
Code:
def prime(num):
if num <= 1:
return False
for i in range(2, num):
if num % i == 0:
return False
return True
Explain: A number is prime if divisible only by 1 and itself. Check all numbers from 2 to num-1. Optimization: only
need to check up to sqrt(num).
Follow-ups:
• What is the sqrt optimization?
• Is 1 prime? (No)
• What is a Sieve of Eratosthenes?
Q28. Armstrong number checker
Code:
num = 153
s = str(num)
total = sum(int(d) ** len(s) for d in s)
print('Armstrong' if total == num else 'Not')
# 1^3 + 5^3 + 3^3 = 153
Explain: An Armstrong number equals the sum of its digits each raised to the power of the number of digits. 153:
1³+5³+3³ = 1+125+27 = 153.
Follow-ups:
• What is another Armstrong number? (370, 371, 407)
• How do you get the number of digits?
• Explain len(str(num)).
Q29. Check perfect number
Code:
num = 6
total = sum(i for i in range(1, num) if num % i == 0)
print('Perfect' if total == num else 'Not')
# Divisors of 6: 1, 2, 3 → sum = 6
Explain: A perfect number equals the sum of its proper divisors (excluding itself). 6 is perfect: 1+2+3=6. Next is 28:
1+2+4+7+14=28.
Follow-ups:
• What is the next perfect number after 6? (28)
• Is 10 perfect? (No, 1+2+5=8)
Q30. Check leap year
Code:
year = 2024
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print('Leap Year')
Explain: The rule: divisible by 4, BUT not by 100, UNLESS also by 400. 2000 is leap (÷400), 1900 is not (÷100 but
not ÷400), 2024 is leap (÷4 not ÷100).
Follow-ups:
• Is 2100 a leap year? (No)
• Is 2000 a leap year? (Yes)
• What is the compound boolean logic here?
Q31. Sum of digits of a number
Code:
n = 12345
total = sum(int(d) for d in str(n))
print(total) # 15
Explain: Convert to string to iterate over digits, convert each back to int, sum them up.
Follow-ups:
• What if the number is negative?
• Find the digital root (keep summing until single digit)?
Q32. Multiplication table
Code:
num = int(input('Enter number: '))
for i in range(1, 11):
print(f'{num} X {i} = {num * i}')
Explain: Simple loop from 1 to 10 using f-strings for formatted output.
Follow-ups:
• Print only even multiples?
• How do you use f-strings vs format()?
SECTION 4 — Python Builtins: Lambda, Map, Filter
Q33. Map: apply a function to all elements
Code:
nums = [1, 2, 3]
result = list(map(lambda x: x + 10, nums))
print(result) # [11, 12, 13]
# Label Even/Odd:
labels = list(map(lambda x: 'Even' if x%2==0 else 'Odd', [1,2,3,4]))
print(labels) # ['Odd', 'Even', 'Odd', 'Even']
Explain: map() applies a function to every element. It returns a lazy iterator, so wrap with list() to get the result.
Follow-ups:
• What is the difference between map() and list comprehension?
• When would you prefer map over comprehension?
• What is a lambda function?
Q34. Filter: keep elements matching a condition
Code:
nums = [1, 2, 3, 4, 5, 6]
result = list(filter(lambda x: x % 2 == 0, nums))
print(result) # [2, 4, 6]
Explain: filter() keeps only elements where the function returns True. Like map(), it's lazy and needs list() to
materialize.
Follow-ups:
• What's the list comprehension equivalent?
• Filter strings longer than 4 characters?
• Combine map and filter?
Q35. Sort list of tuples by second element
Code:
num = [(1, 2), (3, 4), (0, 0)]
print(sorted(num, key=lambda x: x[1]))
# [(0,0), (1,2), (3,4)]
Explain: The key parameter tells sorted() what value to sort by. lambda x: x[1] extracts the second element of each
tuple for comparison.
Follow-ups:
• Sort descending?
• Sort by multiple keys?
• What is [Link](1) and is it faster than lambda?
Q36. Variable arguments with *args
Code:
def abc(*args):
return sum(args)
print(abc(1, 2, 3, 4, 4)) # 14
Explain: *args collects all positional arguments into a tuple. This makes the function flexible — it can accept any
number of arguments.
Follow-ups:
• What is **kwargs?
• What is the difference between *args and a list parameter?
• Can you mix regular args and *args?
QUICK CHEAT SHEET — Python Basics
[Link](k,0)+1 → Standard frequency counting pattern
min/max(dict, key=[Link]) → Find key with min/max value in a dict
set() → O(1) lookup — faster than list for membership check
float('-inf') / float('inf') → Initialize min/max variables safely
n*(n+1)//2 → Sum of 1 to N — use for missing number
s[::-1] → Reverse a string or list in Python
sorted(s1)==sorted(s2) → Check if two strings are anagrams
s2 in s1+s1 → Check if s2 is a rotation of s1
list comprehension → Preferred over map/filter for readability
for/else in Python → else runs only if loop completed without break
Best of Luck! ■