This is the second day of my participation in the August More Text Challenge
About Microsoft
This year, because I want to return to Jiangsu development, I went to interview Microsoft Suzhou, back-end development.
Microsoft’s back-end language is C#/C++, which will have a much smaller market compared to the current mainstream Java/Go in China, so those who want to Go to Microsoft should be prepared to improve their language.
The advantage of Microsoft is that the large platform + foreign companies do not need to be as large as the domestic first-tier Internet. At the same time, because the life in Suzhou is relatively comfortable, the housing price pressure is less than the first-tier cities.
There are also many groups in Microsoft Suzhou, such as M365, Bing, MMD, Edge, etc. Different groups have different working styles.
The interview characteristics
Microsoft interview investigation content includes basic knowledge, project experience, system design, algorithm questions this several pieces, depending on the department and the position will be slightly different, algorithm questions are basic questions for each round of interview, language is not limited, but also the focus of the interview.
Due to the impact of COVID-19, teams interviews will be conducted remotely. For code writing, screen casting can be done in IDE. Of course, some interviewers will provide links and online whiteboard programming. The difficulty of the algorithm problems is leetCode’s Easy or Medium level.
There are many rounds of interview in Microsoft, including 6 rounds, usually 1 round of technical interview +4 rounds of technical interview +1 round of executive interview. The interview cycle is also quite long.
Speaking from the difficulty of interview, my feeling is that the difficulty of Microsoft suzhou interview will be lower than the domestic first-line Internet factory.
If one department fails, Microsoft can interview other departments. I met with three departments in total, namely M365, MMD and EDGE. In the first two departments, I only did about 300 algorithm questions. No matter it was not enough for algorithm interview or technical accumulation, I failed. When I was facing edge, I had done 500 algorithm questions, and many of them were repeated for many times. I was basically familiar with common solutions, and I was also very familiar with algorithm interview. The final result was that the algorithm questions were finished in each round, but unfortunately they were rejected due to background differences.
For how to prepare for the algorithm interview, please refer to the algorithm Interview Guide written between me.
Algorithmic interview questions
Minimum number of changes between two arrays and equal
Two arrays, change one of the number, so that the sum of the two arrays is equal, find the minimum number of changes. Array nums1: for example, [6], nums2:,1,2,2,2,2 [1] to make them and equal, need to change two times, nums1:,2,3,4,5,1 [1], nums2:,1,2,2,2,2 [7]Copy the code
I did not find this question in Leetcode, which also reflects the characteristics of Microsoft interviewers. There are few common questions, which are some cold questions, but they can reflect certain code ability, especially the processing of various boundary cases.
I solved this problem by greedy method in the interview.
class Solution:
def test(self, num1, num2) :
if not num1 and not num2: return 0
s1 = sum(num1)
s2 = sum(num2)
arr = []
d = abs(s1-s2)
if d == 0:
return 0
if s1 < s2:
num1, num2 = num2, num1
for i in num1:
arr.append(i-1)
for i in num2:
arr.append(10-i)
arr.sort()
count = 0
for i in arr[::-1]:
d -= i
count += 1
if d <= 0:
return count
return -1
Copy the code
Remove the K digits
Given a non-negative integer num and an integer k represented as a string, remove the k digits from the number to minimize the remaining digits. Please return the smallest number as a string. Example 1: Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form a new minimum number 1219. Example 2: Input: num = "10200", k = 1 Output: "200" Explanation: Remove the first 1 and the remaining number is 200. Note that the output cannot have any leading zeros. Example 3: Input: num = "10", k = 2 Output: "0" Description: Remove all digits from the original number.Copy the code
This problem is the original problem in Leetcode, 402. Remove K digits.
The time complexity of this problem is O(n), which is greedy + monotone stack.
class Solution:
def removeKdigits(self, num: str, k: int) - >str:
numStack = []
# Build monotonically increasing number strings
for digit in num:
while k and numStack and numStack[-1] > digit:
numStack.pop()
k -= 1
numStack.append(digit)
# If K > 0, delete the last K characters
finalStack = numStack[:-k] if k else numStack
# Erase leading zeros
return "".join(finalStack).lstrip('0') or "0"
Copy the code
Reorder strings by frequency and relative position
Input String: 123123412345 Output String: 111222333445 Resorts the String by the frequency of the letters, or by relative order if the frequency is the sameCopy the code
This problem is a variant of leetCode 1636. Sort an array by frequency in ascending order. When doing this problem, try not to think too complicated.
I’ve developed my own Python one-line solution to this problem.
class Solution:
def interview(self, items) :
return "".join(sorted(list(items), key=lambda x: (items.count(x), -items.index(x)), reverse=True))
Copy the code
Is there a continuous subarray of sum K
Enter an array, such as [1,2,3], and a target value to determine if there are contiguous sums of subarrays for the target valueCopy the code
This problem is actually a simplified version of leetcode’s 325 and the length of the largest array equal to k, and the interviewer only wanted me to figure out if there was a solution.
Similar to this kind of continuous subarray problem, want to think of using hash table + prefix sum idea to do, otherwise violent method of time complexity will be very exaggerated.
So what I’ve given you here is the solution to the original problem in leetcode.
class Solution:
def maxSubArrayLen(self, nums: List[int], k: int) - >int:
dic = {0: -1}
s = res = 0
for i in range(len(nums)):
s += nums[i]
if s - k in dic:
res = max(i-dic[s-k], res)
if s not in dic:
dic[s] = i
return res
Copy the code
Matches make a square
Remember the fairy tale "The Little Match Girl"? Now, you know how many matches the little girl has, please find a way to make a square using all the matches. Matches can't be broken, they can be joined together, and each match must be used. Enter the number of matches the little girl has, each match represented by its length. The output is whether you can form a square with all the matches. Example 1: Input: [1,1,2,2,2] Output: true Explanation: Can form a square of length 2 with two matches on each side.Copy the code
This is the original problem in Leetcode: 473. Matches make squares
I wanted to use greed to do it at first, but later found it very troublesome. Fortunately, I immediately reacted and switched to backtracking.
class Solution:
def makesquare(self, nums: List[int]) - >bool:
if not nums: return False
s = sum(nums)
If the perimeter is not divisible by 4, return False
if s % 4! =0: return False
w = s // 4
Sort the array from the largest to the smallest. This is a greedy way to find solutions much faster
nums.sort(reverse=True)
def _dfs(index, w_arr) :
The array must all be 0, otherwise return False
if index == len(nums):
return all([i==0 for i in w_arr])
result = False
for j in range(len(w_arr)):
If two consecutive values of w_arr are the same, you can skip it
if j > 0 and w_arr[j] == w_arr[j-1] :continue
# try to deduct nums[index]
if w_arr[j] >= nums[index]:
w_arr[j] -= nums[index]
if _dfs(index+1, w_arr):
return True
w_arr[j] += nums[index]
return result
return _dfs(0, [w,w,w,w])
Copy the code
The minimum difference between the sum of the two numbers and the target value
Find minimun abs(val[a] + val[b]) in an integer array.[2, -1000, 0, 33, -15, -100, -1]
Copy the code
This problem is a variation of the classic sum of two numbers, as well as this problem in Leetcode: 1099. Sum of two numbers less than K
Because I’ve done a lot of this kind of problem, it’s easy to write it with sort + double pointer.
class Solution:
def interview(self, nums) :
if len(nums) < 2:
return -1
nums.sort()
min_value = float('inf')
i, j = 0.len(nums) - 1
while i < j:
s = nums[i] + nums[j]
if s == 0:
return 0
elif s < 0:
i += 1
else:
j -= 1
min_value = min(min_value, abs(s))
return min_value
Copy the code
Quick sort
Yes, quicksort is also a common question in the interview, I have encountered in many other interviews besides Microsoft interview, the principle of quicksort, and the average complexity O(nlogn), and the worst time complexity O(n^2).
class Solution:
def sortArray(self, nums) :
n = len(nums)
def quick(left, right) :
if left >= right:
return nums
pivot = left
i = left
j = right
while i < j:
while i < j and nums[j] > nums[pivot]:
j -= 1
while i < j and nums[i] <= nums[pivot]:
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[pivot], nums[j] = nums[j], nums[pivot]
quick(left, j - 1)
quick(j + 1, right)
return nums
return quick(0, n - 1)
Copy the code
Leetcode also has a special topic for sorting arrays: 912. Sorting arrays
The square root of x
Implement the int SQRT (int x) function. Calculates and returns the square root of x, where x is a non-negative integer. Since the return type is an integer, only the integer part of the result is retained, and the fractional part is omitted. Example 1: Input: 4 Output: 2 Example 2: Input: 8 Output: 2 Description: The square root of 8 is 2.82842... Because the return type is an integer, the decimal part will be omitted.Copy the code
The square root of 69. X
But boundary processing is particularly error-prone, so double check.
class Solution:
def mySqrt(self, x: int) - >int:
l, r, ans = 0, x, -1
while l <= r:
mid = (l + r) // 2
if mid * mid <= x:
ans = mid
l = mid + 1
else:
r = mid - 1
return ans
Copy the code
A string with only one different character
A set of lists ['abcd', 'ACdb ',' aACd '] that exist equal to another element if only one character is replaced, and return True otherwise FalseCopy the code
1554. A string with only one different character, but less popular.
class Solution:
def differByOne(self, dict: List[str]) - >bool:
Record all the different strings that might exist in the iterated string
c = set(a)for i in dict:
for j in range(len(i)):
s = i[:j] + '. ' + i[j + 1:]
if s in c:
return True
c.add(s)
return False
Copy the code
In recent times
Given a time in the form of HH:MM, construct the next time closest to the current time using the current number. Each occurrence number can be used an unlimited number of times. You can assume that a given string must be valid. For example, "01:34" and "12:09" are legal, "1:34" and "12:9" are illegal. Example 1: Input: "19:34" Output: "19:39" Explanation: The most recent time constructed from the numbers 1, 9, 3, and 4 is 19:39, 5 minutes later. It's not 19:33 because it's 23 hours and 59 minutes later. Example 2: Input: "23:59" Output: "22:22" Explanation: The most recent time constructed from the numbers 2, 3, 5, and 9 is 22:22. The answer must be sometime the next day, so choose the smallest constructible moment.Copy the code
This question is also the original one in LeetCode, but it is very unpopular: 681. At that time, because the language used by the interviewer was different from that of the interviewer, and the interviewer saw that I had to brush a lot of questions, so I chose a question that few people had done before, which could test the code ability and paid attention to boundary value processing.
However, when DOING this problem, I have accumulated 500 questions, a little debugging, so the test cases have passed, but also by the interviewer’s praise.
class Solution:
def nextClosestTime(self, time: str) - >str:
digit_set = set(a)for c in time:
ifc ! =':':
digit_set.add(c)
if len(digit_set) == 1:
return time
origin_minute = int(time[0:2]) * 60 + int(time[3:)#time converts to minutes
candidates = set(a)def backtrace(path: str) - >None:
if len(path) == 4:
candidates.add(path)
return
for c in digit_set:
path += c
backtrace(path)
path = path[ :-1] # back. Memory explodes without backtracking
backtrace("")
res = 0
first_calc = True
for s in candidates:
H = int(s[0:2])
M = int(s[2:4])
if 0 <= H < 24 and 0 <= M < 60:
cur = H * 60 + M Current time (in minutes)
if cur == origin_minute: # is time itself, so skip it
continue
if first_calc == True: # first calculation
res = cur
first_calc = False
else: # Not the first time
cur_diff = (cur + 24*60 - origin_minute) % (24*60) Every moment smaller than time is counted as the next day
res_diff = (res + 24*60 - origin_minute) % (24*60)
if cur_diff < res_diff:
res = cur
H, M = res//60, res%60
res_s = ""
if H < 10:
res_s += '0'
res_s += str(H)
res_s += ':'
if M < 10:
res_s += '0'
res_s += str(M)
return res_s
Copy the code
Mobile zero
Given an array nums, write a function to move all zeros to the end of the array while preserving the relative order of the non-zero elements. Example: input: [0,1,0,3,12] output: [1,3,12,0,0]Copy the code
At that time, I was very happy to get this problem, because it is too classic, I have done more than 5 times, easy to fix.
283. Move zero
class Solution:
def moveZeroes(self, nums: List[int]) - >None:
""" Do not return anything, modify nums in-place instead. """
i = 0
for j in range(len(nums)):
ifnums[j] ! =0:
nums[i], nums[j] = nums[j], nums[i]
i += 1
return nums
Copy the code
Find the percentile of the log
Web server log format: GET/API /test 200 333ms Calculate the hundredth of the time in the log fileCopy the code
This problem is not strictly algorithmic, it’s just a scenario from everyday work that I can easily do in Python
class Solution:
def interview(self, arr, target) :
# target: decimal from 0 to 1
length = len(arr)
index = int(length*target)
print(index)
time_arr = []
for s in arr:
time = int(s.split()[-1] [: -2])
time_arr.append(time)
time_arr.sort()
print(time_arr)
return time_arr[index]
if __name__ == "__main__":
arr = ["GET /api/test 200 333ms"."GET /api/test 200 222ms"."GET /api/test 200 200ms"]
arr1 = ["GET /api/test 200 333ms"."GET /api/test 200 222ms"."GET /api/test 200 20ms"."GET /api/test 200 1ms"]
a = Solution()
print(a.test(arr, 0.5))
print(a.test(arr1, 0.5))
print(a.test(arr, 0.2))
Copy the code
And are all contiguous subarrays of length k greater than 1
,1,5,6,0 input: [0] k = 6 output:,1,5 [0] [1, 5] [6, 0] for a minimum length of 2Copy the code
This question has many similar questions in Leetcode, such as: 560. And are subarrays of K
Because I’ve trained for this type of problem, so I know how to do it with hash tables and prefixes, and I can do it pretty quickly.
class Solution:
def interview(self, arr, target) :
hashmap = collections.defaultdict(list)
hashmap[0].append(-1)
s = 0
res = []
for i in range(len(arr)):
s += arr[i]
if s - target in hashmap:
left_arr = hashmap[s-target]
for j in left_arr:
if i - j > 1:
res.append(arr[j+1:i+1])
hashmap[s].append(i)
return res
Copy the code
The value is expressed as an integer
201
two hundred and one
2001
two thousand and one
20001
twenty thousand and one
200001
two hundred thousand and one
2000001
two million and one
20 000 001
twenty million and one
200 000 001
two hundred million and one
200 300 001
two hundred million and three hundred thousand and one
two hundred million three hundred thousand and one
Copy the code
This problem is not easy and there are many things to consider. In order to prevent time shortage, I discussed with the interviewer and only completed these use cases listed above.
Leetcode has a sister problem, 273
My following solution can be optimized, which I wrote in the interview.
class Solution:
def interview(self, s) :
num_map = {
'one': 1.'two': 2.'three': 3.'hundred': 100.'thousand': 1000.'million': 1000000.'twenty': 20
}
res = 0
cur = 1
for i in s.split():
ifi ! ='and':
cur *= num_map[i]
else:
res += cur
cur = 1
res += cur
return res
if __name__ == "__main__":
a = Solution()
print(a.test("two thousand and one"))
print(a.test("twenty thousand and one"))
print(a.test("two hundred million and one"))
print(a.test("two hundred million and three hundred thousand and one"))
Copy the code
The interview feeling
At the beginning of the algorithm interview, I was very nervous, and often my mind went blank when I was nervous. Even I could not figure out the solution to the questions I had done before.
Later, I thought bitterly that I still didn’t practice enough, so I practiced the common questions repeatedly to deepen my understanding, and simulated the real interview scene. I wrote the whiteboard once and the IDE once.
Another thing to note is that you can take the interviewer as a partner. If you really can’t figure out a solution to a problem, you can ask him for hints instead of thinking hard and not giving the interviewer feedback, which is very bad.
Finally, after writing, it is a good habit to actively think of test cases and corner cases.
Although I did not get the offer from Microsoft, during the process of preparing for the interview with Microsoft, I mastered the algorithm more and more deeply. When meeting with other companies, the algorithm question was not difficult for me, and FINALLY I got the ideal offer.
Interview with programmer interview is more and more volume, the algorithm is higher and higher, the importance of algorithm does not like teachers just recite in advance, the algorithm is a skill that requires training day after day, from this Angle for, never lose learning algorithm, in the future, you will thank to this question is hard at the moment algorithm.