Basics

This page deals with Basic Python Questions

There are some common programming techniques that you must be familiar with if you want to be comfortable enough to solve Python questions live during an interview. Here we have summarized a few of such techniques but do hone your skills using platforms like Leet code to ensure that you perform well during interviews.

We have collated some resources from the internet as a starting point to help you prepare on this:

Questions

[SNAPCHAT] Palindrome Checker

Given a string, determine whether any permutation of it is a palindrome.

For example, carerac should return true, since it can be rearranged to form racecar, which is a palindrome. sunset should return false, since there’s no rearrangement that can form a palindrome.

Answer

# A string can be a palindrome only if it has even pair of characters and at max 1 odd character
def palindrome(x):
    char_dict = {}
    for i in x:
# we will check if the element exists else we will add it to the dictionary
        try:
            char_dict[i] = char_dict[i] + 1
        except:
            char_dict.update({i:1})
 # next we will create a list of element counts and use list comprehension 
 # to check if odd element count is 1 and rest all even           
    check = list(char_dict.values())
    if (len([temp for temp in check if temp%2==1]) == 1 and len([temp for temp in check if temp%2==0]) > 1):
        return "palindrome"
    else:
        return "not palindrome"
    
print(palindrome("carerac"))
print(palindrome("abc"))
Pattern Generation

Write a function to generate this pattern: 1 2 3 4 5 6

Now change the code to output 1 1 2 1 2 3

Answer

def pyramid(n):
    counter = 1
    max = 1
    while(max<n):
        for i in range(max, max+counter): # for the second pattern change max to 1
            print(i, end=" ")
            max=max+1
        counter=counter+1
        print(" ")
    
pyramid(6)
[UBER] Sum to N

Given a list of positive integers, find all combinations that equal the value N.

Example:

integers = [2,3,5], target = 8,

output = [[2,2,2,2],[2,3,3],[3,5]]

Answer

We will solve it in 2 ways, one using itertools the other one using recursion:

def combinationSum(candidates, target):
    ans = []                                        # for adding all the answers
    def traverse(candid, arr, sm):                  # arr : an array that contains the accused combination; sm : is the sum of all elements of arr 
        if sm == target: ans.append(arr)            # If sum is equal to target then add it to the final list
        if sm >= target: return                     # If sum is greater than target then no need to move further.
        for i in range(len(candid)):                # we will traverse each element from the array.
            traverse(candid[i:], arr + [candid[i]], sm+candid[i])   #most important, splice the array including the current index, splicing in order to handle the duplicates.
    traverse(candidates,[], 0)
    return ans

combinationSum([2, 3, 5], 8)
import itertools
integers = [2,3,5]
target = 8
final = []
# output = [[2,2,2,2],[2,3,3],[3,5]]

max = target//min(integers)
for i in range(1,max+1):
  a = list(itertools.combinations_with_replacement(integers,i))
  for k in a:
    
    if sum(list(k)) == target:
      final.append(k)

print(final)
[STARBUCKS] Max Profit

Given a list of stock prices in ascending order by datetime, write a function that outputs the max profit by buying and selling at a specific interval.

Example:

stock_prices = [10,5,20,32,25,12]

buy –> 5 sell –> 32

Answer

li = [10,5,20,32,25,12]
diff = 0
for i,j in enumerate(li):
    try:
        if(diff<(max(li[i+1:])-j)):
            diff = max(li[i+1:])-j
            buy = j
            sell = max(li[i+1:])
        print(j, max(li[i+1:]))
    except:
        print("end")
    
print(buy, sell, diff)
[IBM] Isomorphic string check

Write a function which will check if each character of string1 can be mapped to a unique character of string2.

Example: string1 = ‘donut’ string2 = ‘fatty’

string_map(string1, string2) == False # as n and u both get mapped to t

string1 = ‘enemy’ string2 = ‘enemy’

string_map(string1, string2) == True # as e’s get mapped to e even though there is two e

string1 = ‘enemy’ string2 = ‘yneme’

string_map(string1, string2) == False # as e’s dont get mapped uniquely

Answer

def string_map(string1, string2):    
    if(string1==string2):
        status = True
    elif(len(string1)!=len(string2)):
        status = False
    else:
        tempstore = {}
        for i,j in enumerate(string1):
            if(j in tempstore):               
                if(tempstore[j] != string2[i]):
                    status = False
                    break
            elif(string2[i] in tempstore.values()):
                    status = False
                    break
            else:
                tempstore[j] = string2[i]
                status = True
    return status

print(string_map('enemy', 'enemy'))
print(string_map('enemy', 'yneme'))
print(string_map('cat', 'ftt'))
print(string_map('ctt', 'fat'))
print(string_map('cat', 'fat'))
[WORKDAY] Sorted String merge

Given two sorted lists, write a function to merge them into one sorted list.

What’s the time complexity?

Answer

def mergeArrays(arr1, arr2):
    
    n1 = len(arr1)
    n2 = len(arr2)
    arr3 = [None] * (n1 + n2)
    i = 0
    j = 0
    k = 0
    # Traverse both array
    while i < n1 and j < n2:     
        # Check if current element of first array is smaller than current element of second array. 
        # If yes, store first array element and increment first array index. Otherwise do same with second array
        
        if arr1[i] < arr2[j]:
            arr3[k] = arr1[i]
            k = k + 1
            i = i + 1
        else:
            arr3[k] = arr2[j]
            k = k + 1
            j = j + 1
     
    # Store remaining elements
    # of first array
    while i < n1:
        arr3[k] = arr1[i];
        k = k + 1
        i = i + 1
 
    # Store remaining elements
    # of second array
    while j < n2:
        arr3[k] = arr2[j];
        k = k + 1
        j = j + 1
    print("Array after merging")
    for i in range(n1 + n2):
        print(str(arr3[i]), end = " ")
 

arr1 = [1, 3, 5, 7]
arr2 = [2, 4, 6, 8]
mergeArrays(arr1, arr2)

# Next coming to the time complexity it is linear as the execution time of the algorithm grows in direct proportion to the size of the data set it is processing.
# For merging two arrays, we are always going to iterate through both of them no matter what, 
# so the number of iterations will always be m+n and the time complexity being O(m+n) where m = len(arr1) and n = len(arr2)
[POSTMATES] Weekly Aggregation

Given a list of timestamps in sequential order, return a list of lists grouped by week (7 days) using the first timestamp as the starting point.

Example:

ts = [ ‘2019-01-01’, ‘2019-01-02’, ‘2019-01-08’, ‘2019-02-01’, ‘2019-02-02’, ‘2019-02-05’, ]

output = [ [‘2019-01-01’, ‘2019-01-02’], [‘2019-01-08’], [‘2019-02-01’, ‘2019-02-02’], [‘2019-02-05’] ]

Answer

ts = [
    '2019-01-01', 
    '2019-01-02',
    '2019-01-08', 
    '2019-02-01', 
    '2019-02-02',
    '2019-02-05',
]

from datetime import datetime as dt
from itertools import groupby

first = dt.strptime(inp[0], "%Y-%m-%d")
out = []

for k, g in groupby(ts, key=lambda d: (dt.strptime(d, "%Y-%m-%d") - first).days // 7 ):
    out.append(list(g))

print(out)
[MICROSOFT] Find the missing number

You have an array of integers of length n spanning 0 to n with one missing. Write a function that returns the missing number in the array

Example:

nums = [0,1,2,4,5] missingNumber(nums) -> 3

Complexity of O(N) required.

Answer

def missingNumber(nums):

  diff = 0
  miss_num = []
  for i, j in enumerate(nums):
    try:
      t_diff = nums[i+1]-nums[i]
      if t_diff>0:
        for k in range(i+1,i+t_diff):
          # print(k)
          miss_num.append(k)
    except:
      pass
  return miss_num

nums = [0,1,2,5,6]
missingNumber(nums)
[SQUARE] Book Combinations

You have store credit of N dollars. However, you don’t want to walk a long distance with heavy books, but you want to spend all of your store credit.

Let’s say we have a list of books in the format of tuples where the first value is the price and the second value is the weight of the book -> (price,weight).

Write a function optimal_books to retrieve the combination allows you to spend all of your store credit while getting at least two books at the lowest weight.

Note: you should spend all your credit and getting at least 2 books, If no such condition satisfied just return empty list.

Example:

N = 18
books = [(17,8), (9,4), (18,5), (11,9), (1,2), (13,7), (7,5), (3,6), (10,8)]

def optimal_books(N, books) -> [(17,8),(1,2)]

Answer

# Let's take this step by step
import itertools

def optimal_books(N, books):
    print("(Price,Weight) details of books: ",books)
    print("Store Credit: ",N)
    final_books = [] # empty list to store the final books
    # sorting the books by weight as we need the lightest books
    sorted_books = sorted(books, key = lambda x:x[1]) 
    price = [i[0] for i in sorted_books] #list of prices sorted by weight
    
    for i in range(2,len(price)+1):
        templist = (list(itertools.combinations(price,i))) # generating all combinations of price
        res = [sum(j) for j in templist] # summing individual combination to get total price of each combination
        if N in res: # if the result matches traceback traceback and append the combination         
            tempbooks = (templist[res.index(N)])            
            for k in tempbooks:
                final_books.append(sorted_books[price.index(k)])            
            break
            
    return final_books
        
N = 18
books = [(17,8), (9,4), (18,5), (11,9), (1,2), (13,7), (7,5), (3,6), (10,8)]
print("Best Combination: ",optimal_books(N,books))
[WISH] Intersecting Lines

Say you are given a list of tuples where the first element is the slope of a line and the second element is the y-intercept of a line.

Write a function find_intersecting to find which lines, if any, intersect with any of the others in the given x_range.

Example

tuple_list = [(2, 3), (-3, 5), (4, 6), (5, 7)] x_range = (0, 1)

Output

def find_intersecting(tuple_list, x_range) -> [(2,3), (-3,5)]

Answer

# for 2 lines to intersect the formulas used here are:
# y = mx + c
# x = (c2-c1)/(m1-m2)
# https://www.cuemath.com/geometry/intersection-of-two-lines/ Check this link for details of the formula

def intersectinglines(tuple_list,x_range):
    output=[]
    for i in range(len(tuple_list)):
        for j in range(i+1,len(tuple_list)):

            x = (tuple_list[j][1]-tuple_list[i][1])/(tuple_list[i][0]-tuple_list[j][0])
            y = tuple_list[j][1]*x+tuple_list[j][0]

            if x>=x_range[0] and x<=x_range[1]:
                output.extend([tuple_list[i],tuple_list[j]])
    return output

tuple_list = [(2, 3), (-3, 5), (4, 6), (5, 7)]
x_range = (0, 1)

intersectinglines(tuple_list, x_range)
Find the majority element in a list.

a = [2,3,4,6, 6, 2,2] answer --> 2

Answer

a = [2,3,4,6, 6, 2,2]

def major_ele(x):
    counter_dict = {}
    for i in a:
        if i not in counter_dict:
           counter_dict.update({i:1})
        else:
           counter_dict[i] =  counter_dict[i] + 1 
    for i,j in counter_dict.items():
        if j == max(list(counter_dict.values())):
            return i

print(major_ele(a))
[INTUIT] Iterator

Implement an iterator function which takes three iterators as the input and sorts them.

Answer

2 Solutions are provided below:

import heapq

def sorted_merge(*iterators):
    # Use heapq.merge to merge and sort the input iterators
    sorted_iterator = heapq.merge(*iterators)
    
    # Return the sorted iterator
    return sorted_iterator

# Example usage:
if __name__ == "__main__":
    # Create three sorted iterators (lists in this case)
    iterator1 = iter([1, 3, 5, 7])
    iterator2 = iter([2, 4, 6, 8])
    iterator3 = iter([0, 9, 10])
    
    # Merge and sort the iterators
    sorted_iterator = sorted_merge(iterator1, iterator2, iterator3)
    
    # Iterate through the sorted values
    for value in sorted_iterator:
        print(value)
def sort_iterators(it1, it2, it3):
  """Sorts three iterators.

  Args:
    it1: The first iterator.
    it2: The second iterator.
    it3: The third iterator.

  Returns:
    An iterator that yields the sorted elements of the three iterators.
  """
  # Create a list to store the elements of the three iterators.
  elements = []

  # Iterate over the three iterators and add the elements to the list.
  for element in it1:
    elements.append(element)
  for element in it2:
    elements.append(element)
  for element in it3:
    elements.append(element)

  # Sort the list.
  elements.sort()

  # Create an iterator that yields the elements of the sorted list.
  return iter(elements)
[SPLUNK] Last Page Number

We're given a string of integers that represent page numbers.

Write a function to return the last page number in the string. If the string of integers is not in correct page order, return the last number in order.

input = '12345'
output = 5

input = '12345678910111213'
output = 13

input = '1235678'
output = 3

Answer

def get_last_page(int_string):
    print(int_string)
    count = 0
    counter2 = 0
    for i in int_string:
        count = count+1+counter2//10
        counter2 = counter2+1
        if(str(counter2)==int_string[count-1:count+counter2//10]):
            pass
        else:
            return counter2-1
Python Recursion

Explain Python recursion with an example.

Answer

Recursion is a programming technique that allows a function to call itself. This can be useful for solving problems that involve self-similar structures, such as trees and graphs.

def factorial(n): # 6! = 6*3*2*1
  if(n==0 or n==1): # define the base case
    return 1
  return factorial(n-1)*n # recursively call the func

factorial(6)

This function works by calling itself recursively to calculate the factorial. The base cases are when n is 0 or 1, in which case the function simply returns n.

Recursion can be a powerful tool, but it is important to use it carefully. If a recursive function is not designed carefully, it can easily lead to stack overflows.

[INTUIT] Subarray Product Less Than K

This was asked in INTUIT Sr. Data Scientist initial round using Glider

Given an array of integers nums and an integer k, return the number of contiguous subarrays where the product of all the elements in the subarray is strictly less than k.

Example 1:

Input: nums = [10,5,2,6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are:
[10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.

Example 2:

Input: nums = [1,2,3], k = 0
Output: 0

Constraints:

  • 1 <= nums.length <= 3 * 104

  • 1 <= nums[i] <= 1000

  • 0 <= k <= 106

Answer

You are not only required to solve the problem in a limited time frame (~30mins) but the ask is also to ensure that the all test-cases pass and at least one of them fails if the code does not meet the required time complexity even if you get the required answer.

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], max_product: int) -> int:        
        result = 0
        for i in range(1, len(nums)):
            for j, l in enumerate(nums):
                temp = nums[j:j+i]
                res = 1
                for m in temp:
                    res = m*res
                if(res<max_product and len(temp)==i):
                    result +=1      
        return result

The above code fails some test cases as it has O(n^3) complexity. There is the two-pointer or inchworm approach given below which solves the problem along with taking care of the complexity. Click on the Leetcode link above and check the discussions if you want to understand it better:

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], max_product: int) -> int:        
        left = 0
        result = 0
        product = 1
        
        for right in range(len(nums)):
            product *= nums[right]
            
            if product >= max_product:
                while product >= max_product and left <= right:
                    product /= nums[left]
                    left += 1
            
            result += right - left + 1
        
        return result

Reverse Vowels in a String

Given a string s, reverse only all the vowels in the string and return it.

The vowels are 'a', 'e', 'i', 'o', and 'u', and they can appear in both lower and upper cases, more than once.

Example 1:

Input: s = "hello"
Output: "holle"

Example 2:

Input: s = "leetcode"
Output: "leotcede"

Answer

This can be solved using the 2-pointer approach:

class Solution:
    def reverseVowels(self, s: str) -> str:
        s = list(s)
        vow = "aeiouAEIOU"
        left = 0
        right = len(s)-1
        while left < right:
            if s[left] in vow and s[right] in vow:
                
                s[left], s[right] = s[right], s[left]
                
                left += 1; right -= 1
            
            elif s[left] not in vow:
                left += 1
            
            elif s[right] not in vow:
                right -= 1            
        return ''.join(s)
Swap numbers

Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.

Note that you must do this in-place without making a copy of the array.

Example:

Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]

Answer

class Solution:
    def moveZeroes(self, nums: list) -> None:
        slow = 0
        for fast in range(len(nums)):
            if nums[fast] != 0 and nums[slow] == 0:
                nums[slow], nums[fast] = nums[fast], nums[slow]

            # wait while we find a non-zero element to
            # swap with you
            if nums[slow] != 0:
                slow += 1

Algorithm complexity: Time complexity: O(n). Our fast pointer does not visit the same spot twice. Space complexity: O(1). All operations are made in-place

[SALESFORCE] Interpolation

Answer

x = [25, 50, 100]
y = [5.0, 4.0, 3.0]

def interporlate(n):
  if(n in x):
    return y[x.index(n)]
  elif(n > x[-1]):
    x_t = x[-1]-x[-2]
    y_t = y[-1]-y[-2]
    return y[-1] + (y_t / x_t * (n-x[-1]))
  elif(n < x[0]):
    x_t = x[0]-x[1]
    y_t = y[0]-y[1]
    return y[0] + (y_t / x_t * (n-x[0]))
  else:
    for i,j in enumerate(x):
      if n<j:
        break
    x_t = x[i-1]-x[i]
    y_t = y[i-1]-y[i]
    return y[i-1] + (y_t / x_t * (n-x[i-1]))


print(interporlate(50))
print(interporlate(150))
print(interporlate(25))
print(interporlate(75))
[SALESFORCE] Prison Problem

Answer

def prison(size, x, y):
  x_t = list(range(0,6,1))
  y_t = list(range(0,6,1))
  x_t = [a for a in x_t if a not in x]
  y_t = [a for a in y_t if a not in y]

  # accounting for the outer walls, we will add 0 as starting
  # and add +1 to all others
  x_t = list(map(lambda t: t + 1, x_t))
  y_t = list(map(lambda t: t + 1, y_t))
  x_t.insert(0,0)
  y_t.insert(0,0)

  max_x = 1
  max_y = 1

  for i,j in enumerate(x_t):
    try:
      if(max_x< x_t[i+1]-j):
        max_x = x_t[i+1] -j    
    except:
      pass

  for i,j in enumerate(y_t):
    try:
      if(max_y< y_t[i+1]-j):
        max_y = y_t[i+1] -j
    except:
      pass

  return "Max cell size: ", max_x*max_y


prison(5, [3, 2], [0, 1, 3])

Last updated