CodeSignal
Understand the question type through this general-coding-assessment-framework.pdf.
Recommend question order, Q1 -> Q2 > Q3 (look through the question) -> Q4 (brute force if not able to come up an optimal solution) -> Q3(finish) -> Q4(optimize)
Q1 & Q2
For q1, straightforward, understand common used array and string manipulation methods. (5 - 10 lines of code)
For q2, The question can be long, take time to understand the question and solve use the brute force way. (10 - 20 lines of code)
# 2. String Indexing and Slicing
s = "AdvancedPython"
print(s[0]) # First character: 'A'
print(s[-1]) # Last character: 'n'
print(s[2:8]) # Substring from index 2 to 7: 'vanced'
print(s[:7]) # From beginning to index 6: 'Advance'
print(s[::2]) # Every 2nd character: 'Aaceyh'
print(s[::-1]) # Reverse the string
# 3. Common String Methods
text = " Hello, Python World! "
print(text.strip()) # Remove leading and trailing whitespace
print(text.lower()) # Convert to lowercase
print(text.upper()) # Convert to uppercase
print(text.title()) # Capitalize each word
print(text.replace("Python", "C#")) # Replace substring
print(text.find("Python")) # Find index of substring (-1 if not found)
print(text.startswith(" Hello")) # Check if starts with
print(text.endswith("World! ")) # Check if ends with
print("123abc".isalnum()) # Check alphanumeric
print("123".isdigit()) # Check digits only
print("abc".isalpha()) # Check alphabetic only
# 4. Joining and Splitting
words = ["Python", "is", "awesome"]
sentence = " ".join(words) # Join list into a string with spaces
print(sentence) # Output: Python is awesome
split_words = sentence.split(" ") # Split string back into list
print(split_words)
length = [3, 5, 7]
sentence = "#".join(length) # ❌ TypeError: expected str, got int, join would always the iterable elements string
length = [3, 5, 7]
sentence = "#".join(map(str, length)) # ✅ "3#5#7"
sentence = "#".join([str(x) for x in length]) #Alternatively:
print(sentence) # Output: 3#5#7
csv = "3#5#7"
split_numbers = csv.split("#") # Split a string using custom delimiter
print(split_numbers) # Output: ['3', '5', '7']
Q3 - Simulation
25 - 40 lines of code, aim to solve in 15 - 20 minutes
54. Spiral Matrix
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
#spiral order, from outer circle to inner circle
#simulate boundary, use smth to record index
res = []
top,bottom = 0, len(matrix)-1
left,right = 0, len(matrix[0])-1
order_state = "right"
while len(res) < (len(matrix) * len(matrix[0])):
if order_state == "right":
for i in range(left, right+1): # 123
res.append(matrix[top][i])
order_state = "bottom"
top += 1
elif order_state == "bottom": # 69
for j in range(top, bottom+1):
res.append(matrix[j][right])
order_state = "left"
right-=1
elif order_state == "left":
for i in range(right,left-1, -1): #8 7
res.append(matrix[bottom][i])
order_state = "up"
bottom -= 1
elif order_state == "up":
# print(bottom,top,left)
for j in range(bottom, top-1, -1): # 4
res.append(matrix[j][left])
order_state = "right"
#increment the boundary
left += 1
# print(res)
return res
59. Spiral Matrix II
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
#generate in spiral order
# define the boundary
res = [[0]*n for _ in range(n)]
# print(res)
left, right = 0, n
top, bottom = 0, n
count = 1
state = "right"
while count <= (n*n):
if state == "right":
for i in range(left, right):
res[top][i] = count
count += 1
state = "bottom"
top += 1
elif state == "bottom":
for i in range(top, bottom):
res[i][right-1] = count
count += 1
right -= 1
state = "left"
elif state == "left":
for i in range(right-1, left-1,-1):
res[bottom-1][i] = count
count += 1
bottom -= 1
state = "up"
elif state == "up":
for i in range(bottom-1, top-1,-1):
res[i][left] = count
count += 1
left += 1
state = "right"
print(res)
return res
* 48. Rotate Image
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#first transpose then mirror, also in place is hard
n = len(matrix)
def transpose(matrix):
for i in range(len(matrix)):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
transpose(matrix)
# print(matrix)
def mirror(matrix):
for i in range(n):
for j in range(n//2):
matrix[i][j],matrix[i][n-j-1] = matrix[i][n-j-1], matrix[i][j]
mirror(matrix)
* 498. Diagonal Traverse
Got a similar one in the q3. Which request traverse 4 directions.
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
# feel like just going through up and down ?
res = []
state = "up"
r, c = 0, 0
m = len(mat)
n = len(mat[0])
def isvalid(r, c):
if 0 <= r < m and 0 <= c < n:
return True
else:
return False
#change each state based on the valid condition
while len(res) < (m *n):
if state == "up":
while isvalid(r, c):
res.append(mat[r][c])
r -= 1
c += 1
r += 1
c -= 1
state = "down"
if c < (n-1):
c += 1
else:
r += 1
elif state == "down":
while isvalid(r, c):
res.append(mat[r][c])
r += 1
c -= 1
r -= 1
c += 1
state = "up"
if r < (m-1):
r += 1
else:
c += 1
# print(res, r, c)
return res
566. Reshape the Matrix
class Solution:
def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
#if legal
m = len(mat)
n = len(mat[0])
if not m *n == r *c: return mat
res = [[0] *c for _ in range(r)]
# print(res)
flat = []
for i in range(m):
for j in range(n):
flat.append(mat[i][j])
for i in range(len(flat)):
# 12
# if i:
row = i // c
col = i % c
res[row][col] = flat[i]
# print(res,row,col)
# else:
# res[0][0] = flat[i]
return res
766. Toeplitz Matrix
class Solution:
def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
m, n = len(matrix), len(matrix[0])
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] != matrix[i - 1][j - 1]:
return False
return True
835. Image Overlap
from collections import defaultdict
from typing import List
class Solution:
def largestOverlap(self, img1: List[List[int]], img2: List[List[int]]) -> int:
n = len(img1)
ones1 = []
ones2 = []
# Step 1: Record positions of 1s
for i in range(n):
for j in range(n):
if img1[i][j] == 1:
ones1.append((i, j))
if img2[i][j] == 1:
ones2.append((i, j))
# Step 2: Count all translation vectors from img1 -> img2
vector_count = defaultdict(int)
for x1, y1 in ones1:
for x2, y2 in ones2:
dx = x2 - x1
dy = y2 - y1
vector_count[(dx, dy)] += 1
print(vector_count)
# Step 3: Return the maximum overlap
return max(vector_count.values() or [0])
2373. Largest Local Values in a Matrix
class Solution:
def largestLocal(self, grid: List[List[int]]) -> List[List[int]]:
n = len(grid)
maxLocal = [[0] * (n - 2) for _ in range(n - 2)]
for i in range(1, n - 1):
for j in range(1, n - 1):
tempMax = float('-inf')
# Traverse the 3x3 subgrid centered at (i, j)
for r in range(i - 1, i + 2):
for c in range(j - 1, j + 2):
tempMax = max(tempMax, grid[r][c])
maxLocal[i - 1][j - 1] = tempMax
return maxLocal
867. Transpose Matrix
class Solution:
def transpose(self, matrix: List[List[int]]) -> List[List[int]]:
m, n = len(matrix), len(matrix[0])
trans = [[0] * m for _ in range(n)]
for i in range(m):
for j in range(n):
trans[j][i] = matrix[i][j]
return trans
68. Text Justification - Low chance
class Solution:
def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
n = len(words)
word_arr = []
word_arr_len = []
curr_len = 0
temp = []
temp_len = []
for word in words:
word_len = len(word)
if word_len + curr_len + len(temp)-1 < maxWidth:
temp.append(word)
temp_len.append(len(word))
curr_len += len(word)
else:
word_arr.append(temp)
word_arr_len.append(temp_len)
curr_len = len(word)
temp = [word]
temp_len = [len(word)]
word_arr.append(temp)
word_arr_len.append(temp_len)
#now justify the length, handle the last row separately
for i in range(len(word_arr)):
remain_space = maxWidth - sum(word_arr_len[i])
# print(remain_space)
empty_slot = len(word_arr[i]) - 1
if i != len(word_arr)-1 and empty_slot != 0:
for j in range(remain_space): # add space after equally
insert_index = j % empty_slot
word_arr[i][insert_index] += ' '
elif empty_slot == 0:
for _ in range(remain_space):
word_arr[i][-1] += ' '
else:
for j in range(empty_slot):
word_arr[i][j] += ' '
for _ in range(remain_space - empty_slot):
word_arr[i][-1] += ' '
res = []
for i in range(len(word_arr)):
res.append(''.join(word_arr[i]))
print(word_arr, word_arr_len)
return res
Q4 - Algorithm
20 - 35 lines of code.
3160. Find the Number of Distinct Colors Among the Balls
class Solution:
def queryResults(self, limit: int, queries: List[List[int]]) -> List[int]:
# hashmap -> 1 -> 1
color_count = defaultdict(int) # color: count
# ball color can get replaced
# hashmap: list
color_index = {} # ball: color
res = []
for query in queries:
x, y = query
if x in color_index:
color = color_index[x]
color_count[color] -= 1
if color_count[color] == 0:
del color_count[color]
color_index[x] = y
color_count[y] += 1
else:
color_index[x] = y
color_count[y] += 1
res.append(len(color_count))
return res
3159. Find Occurrences of an Element in an Array
class Solution:
def occurrencesOfElement(self, nums: List[int], queries: List[int], x: int) -> List[int]:
# put the ans in the res index list -> brute force, use a loop
# list[3]1 [index:]
index_ls = []
res = []
for i,num in enumerate(nums):
if num == x:
index_ls.append(i)
print(index_ls)
for query in queries:
if len(index_ls) >= query:
res.append(index_ls[query-1])
else:
res.append(-1)
return res
532. K-diff Pairs in an Array
class Solution:
def findPairs(self, nums: List[int], k: int) -> int:
freq = Counter(nums)
res = 0
for num in freq:
if k !=0 and num + k in freq:
res += 1
if k == 0 and freq[num] > 1:
res += 1
return res
1248. Count Number of Nice Subarrays
class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
left = 0
n = len(nums)
q_size = 0
count = 0
move = 0
for right, num in enumerate(nums):
if num % 2 != 0:
q_size += 1
if q_size == k:
#need to shrink the window but also count the moves
move = 0
while q_size == k:
q_size -= nums[left] % 2 # if odd will give a result 1 and end the loop
move += 1 # 1 subarray
left += 1
count += move
print(num,count)
return count
923. 3Sum With Multiplicity
class Solution:
def threeSumMulti(self, arr: List[int], target: int) -> int:
f_count = Counter()
n = len(arr)
res = 0
MOD = 10 ** 9 + 7
for second in range(n):
for third in range(second+1, n):
find = target - arr[second] - arr[third]
if find in f_count:
res += f_count[find]
#update the first index at the end to ensure the order access
f_count[arr[second]] += 1
return res % MOD
954. Array of Doubled Pairs
class Solution:
def canReorderDoubled(self, arr: List[int]) -> bool:
#convert to abs
freq = Counter(arr)
print(sorted(freq, key=abs)) #output a list
for num in sorted(freq, key=abs):
if freq[num * 2] < freq[num]:
return False
freq[num*2] -= freq[num]
return True
2131. Longest Palindrome by Concatenating Two Letter Words
from collections import Counter
from typing import List
class Solution:
def longestPalindrome(self, words: List[str]) -> int:
word_count = Counter(words)
count = 0
for word in word_count.keys():
rev = word[::-1]
if word[0] == word[1]:
# symmetric case like "gg"
pairs = word_count[word] // 2
count += pairs * 4
word_count[word] -= pairs * 2
elif rev in word_count:
# asymmetric pair like "ab" and "ba"
pairs = min(word_count[word], word_count[rev])
count += pairs * 4
# del word_count[word]
# del word_count[rev]
word_count[word] = 0
word_count[rev] = 0
# After all pairing, try to use a center word like "gg"
for word in word_count:
if word[0] == word[1] and word_count[word] > 0:
count += 2
break
return count