Algorithmic real questions for interviews in major factories

Huawei

The second side of the ICT optical product department

integer split

Niuke Original Title: Integer Split

An integer can always be split into sums of powers of 2, for example:
7 = 1+2+4
7 = 1+2+2+2
7 = 1+1+1+4
7 = 1+1+1+2+ 2
7 = 1+1+1+1+1+2
7 = 1+1+1+1+1+1+1
There are six different splits in total.
Another example: 4 can be split into:
4 = 4
4 = 1 + 1 + 1 + 1
4 = 2 + 2
4 = 1+1+2
Use f(n) to represent the number of different splits of n, such as f (7)=6. It is required to write a program, read in n (not exceeding 1000000), and output f(n)%1000000000.

Analysis:
Divide into odd numbers and even numbers for discussion
. When N is an odd number, it must contain an odd number component 1, because the other components are all even numbers. So it can only be obtained by +1 through its previous number N-1
. When N is an even number, it can have an odd component 1 or not. So it can be obtained by +1 through its previous number N-1, or it can be obtained by multiplying the components of the N//2 number by 2, so that the components inside are all even numbers. In summary, the dynamic regression equation is:
dp
[ i ] = { dp [ i − 1 ] , i % 2 ! = 0 dp [ i − 1 ] + dp [ i / / 2 ] , i % 2 = = 0 dp[i] = \begin{cases} dp[ i-1], & i\%2 != 0 \\ dp[i-1] + dp[i//2], & i\%2 == 0 \end{cases}dp[i]={ dp[i1],dp[i1]+dp[i//2],i%2!=0i%2==0

Dynamic programming of Python source code:

number = int(input())

dp = [0] * (number + 1)
dp[1] = 1

for i in range(2, number + 1):
    if i&1 == 1:
        dp[i] = dp[i-1] % 1000000000
    else:
        dp[i] = (dp[i-1] + dp[i>>1]) % 1000000000

print(dp[-1])

Backtracking of Python source code:

def demo(n):
    res = []
    path = []

    def backtracking(val, startIndex):
        if val == 0:
            res.append(path[:])
            return
        if val < 0:
            return

        i = startIndex
        while 2 ** i <= val:
            val -= 2 ** i
            path.append(2 ** i)
            backtracking(val, i)
            path.pop()
            val += 2 ** i
            i += 1
    
    backtracking(n, 0)
    return res

res = demo(7)
print(len(res))
print(res)

Print result:

6
[[1, 1, 1, 1, 1, 1, 1], 
[1, 1, 1, 1, 1, 2], 
[1, 1, 1, 2, 2], 
[1, 1, 1, 4], 
[1, 2, 2, 2], 
[1, 2, 4]]

Upgraded version:
An integer is split into a split method that is less than or equal to the sum of its non-negative numbers, that is, it does not limit its split into a power of 2

Analysis:
Four solutions to the integer split problem
Problem definition:
dp[i][j]: indicates the number of types that the number i can be split by an integer up to j

The dynamic migration equation is divided into three cases:
1) When i=j, the number of split species dp[i][j] at this time will only be one more than the number of dp[i][j-1] In this case, i can be represented by j. So dp[i][j]=dp[i][j-1]+1
2) When i<j, the number of splits at this time dp[i][j] is equal to dp[i][i ], because they cannot split the integer i for j greater than i, which means that the part j greater than i has no effect. So dp[i][j]=dp[i][i]
3) When i>j, the number of splits dp[i][j] at this time consists of two situations, first, split There is a number j in it, and the number of types in this case is dp[ij][j]; second, there is no number j in the split, and the number of types in this case is dp[i][j-1] dp [
i ] [ j ] = { dp [ i ] [ j − 1 ] + 1 , i = = jdp [ i ] [ i ] , i < jdp [ i − j ] [ j ] + dp [ i ] [ j − 1 ] , i > j dp[i][j] = \begin{cases} dp[i][j-1] + 1, & i==j \\ dp[i][i], & i<j \\ dp[ij][j] + dp[i][j-1], & i>j \end{cases}dp[i][j]= dp[i][j1]+1,dp[i][i],dp[ij ] [ j ]+dp[i][j1],i==ji<ji>j

Initialization:
When i=1 or j=1, there is only one case

Dynamic programming of Python source code:

def dfs(n):
    dp = [[0] * (n+1) for _ in range(n+1)]
    for i in range(1, n+1): dp[i][1] = 1
    for i in range(1, n+1): dp[1][i] = 1

    for i in range(2, n+1):
        for j in range(2, n+1):
            if i == j: dp[i][j] = dp[i][j-1] + 1
            elif i < j: dp[i][j] = dp[i][i]
            else: dp[i][j] = dp[i-j][j] + dp[i][j-1]

    return dp[-1][-1]

Backtracking of Python source code:

def demo(n):
    res = []
    path = []

    def backtracking(val, startIndex):
        if val == 0:
            res.append(path[:])
            return
        if val < 0:
            return

        i = startIndex
        while i <= val:
            val -= i
            path.append(i)
            backtracking(val, i)
            path.pop()
            val += i
            i += 1
    
    backtracking(n, 1)
    return res

res = demo(4)
print(len(res))
print(res)

Print result:

5
[[1, 1, 1, 1], 
[1, 1, 2], 
[1, 3], 
[2, 2], 
[4]]

Terminal BG-AI and smart full-scenario side

string conversion

Niu Ke Mianjing: Huawei-AI Engineer-Consumer BG-Mianjing Mianjing
finishing plan - the sixth
insert image description here
analysis:
Greedy thinking
1) For each character in the target, go to the block to match one by one
2) If it matches If successful, both target and block are shifted to the right by one bit, and continue to match.
3) If the match is unsuccessful, res+1, and the block starts to match from the beginning.
4) If the entire block has not been matched successfully, return -1, indicating that it cannot Get the target from the block

Python source code:

def demo(target, block):
    res = 0
    i = 0
    while i < len(target):
        j = 0
        flag = True
        while j < len(block):
            if i < len(target) and target[i] == block[j]:
                i += 1
                flag = False
            j += 1
        if flag: return -1
        res += 1
    return res

target = 'abcd'  # 'aaa', 'abcd'
block = 'bcad'  # 'ad', 'bcad'
print(demo(target, block))

Minimum string without consecutive 1's

Given a string containing only 0s and 1s, determine whether there are consecutive 1s in it. If there is, then output the minimum value string without consecutive 1s that is larger than this string. If not, do nothing.
Example: Given '11011', output '100000'; given '10011', output '10100'.

Analysis:
still greedy thinking
1) Search from left to right, find the first two consecutive 1s, if not, return the original string directly
2) Change the previous symbol (0) to 1 at the continuous position, The following symbols all become 0.
3) After the transformation, when continuing to check, there are continuous 1, if not, return directly

Python source code:

def demo(strInput):
    start = check(strInput)

    while start != -1:
        if start == 0:
            strInput = '1' + '0'*len(strInput)
        else:
            strInput = strInput[:start-1] + '1' + '0'*(len(strInput)-start)
        start = check(strInput)

    return strInput

def check(strInput):
    for i in range(len(strInput)-1):
        if strInput[i] == strInput[i+1] and strInput[i] == '1':
            return i
    return -1

print(demo('10011'))

collection subset

Given a set, output all subsets of that set and give the time complexity of the algorithm you write.
Example: Given a set [1, 2, 3], output [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]].

LeetCode original title: Sword Pointer Offer II 079. All subsets

Analysis:
backtracking thinking, divided into two cases, that is, whether the current element is placed in the subset

Python source code:

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []

        def backtracking(cur):
            if cur == len(nums):
                res.append(path[:])
                return
            
            # 当前元素放入path中
            path.append(nums[cur])
            backtracking(cur + 1)
            path.pop()

            # 当前元素不放入path中
            backtracking(cur + 1)

        backtracking(0)
        return res

multiplication of large numbers

insert image description here

Read in two numbers as strings, write a function to multiply them, and return them as a string.

Niuke original title: NC10 large number multiplication

Analysis:
Excellent Solution:
[Algorithm] Large Number Multiplication Problem and Its Efficient Algorithm
Karatsuba Large Number Multiplication Algorithm
Python Large Number Multiplication

Python source code:

class Solution:
    def solve(self , s: str, t: str) -> str:
        # write code here
        if s == '0' or t == '0': return '0'
        res = [0] * (len(s) + len(t))
        sList = list(s)
        tList = list(t)
        sList.reverse()
        tList.reverse()
        # 将t里面的每个数字与s相乘,并保存在对应为res位数上
        for i in range(len(sList)):
            for j in range(len(tList)):
                res[i+j] += int(sList[i]) * int(tList[j])
        # 将res位数上的数字进行取余和求商运算,余数放在当前位置上,商进行进位
        for i in range(len(res)):
            temp = res[i]
            res[i] = str(temp % 10)
            if i < len(res)-1: res[i+1] = res[i+1] + temp // 10
        # 返回结果,注意移除res前面的0
        res.reverse()
        resStr = ''.join(res)
        for i in range(len(resStr)):
            if resStr[i] != '0': break
        resStr = resStr[i:]
        return resStr

longest palindromic substring

LeetCode original question: 5. Longest palindrome substring

Two sides of terminal BG-AI and intelligent full scene

sliding window

LeetCode original question: 209. Minimum length subarray

baidu

Baidu's autonomous driving side

Shorthand for repeating characters

There is a shorthand for repeated characters
(1) The repeated part will be recorded in the form of "(repeated content)<repeated times>", and there may be a nested abbreviation relationship
(2) The non-repeated part is recorded as it is;
given first A string str, please implement a function to restore the content before the string shorthand, str is only composed of lowercase letters, numbers, (), <>.
For example:
str="abc(d)<2>", the string before the shorthand is: "abcdd"
str="a(b(c)<2>d)<3>e", the string before the shorthand is: " abccdbccdbccde"

Analysis:
The first idea is simple, that is to use the stack, then how to record these special characters and letters made me difficult in the interview again, I didn’t think about it for a while, and I will understand after a while, the steps are as follows: 1
) Push the characters in str into the stack according to the subscript i loop
2) Determine whether the current character is a symbol ")", if it is, it means that a repeated character is currently encountered, here we need to pay attention to one point, if it is a ")" symbol , then execute steps 3), 4), and 5). After the execution, the loop subscript i needs to skip the content in "<>". If it is not the ")" symbol, then i+1 and enter the next round of loop
3 ) Read the content inside the symbol ")" behind "<>", that is, get the number of repetitions
4) Read the symbol ")" from the front to the nearest one"("Symbol, the implementation method is that the while loop pops from the stack Pop out the elements, put the popped elements in a new temporary stack temp_stack, and stop the loop when you know the symbol "(", at this time, the current repeated content is stored in temp_stack 5) According to the number of repetitions, and then in
order Put the elements of temp_stack back into the stack stack. Note that when you put them back, you still need to traverse from the top of the temp_stack stack.
6) Until all the elements in the string str are traversed, the content before the shorthand is stored in the stack. Directly return "".join(stack) to complete the entire function

Python source code

def demo(strInput):
    stack = []
    i = 0
    while i < len(strInput):
        if strInput[i] == ')':
            # 读取 <> 里面的重复次数
            j = i + 2 # 跳过 < 符号
            times = ""
            while strInput[j] != '>':
                times += strInput[j]
                j += 1
            times = int(times)
            # 读取 ) 符号到最近 ( 符号里面的重复内容
            str_val = stack.pop()
            temp_stack = []
            while str_val != '(':
                temp_stack.append(str_val)
                str_val = stack.pop()
            # 根据重复次数依次将temp_stack里面的元素再放回stack中
            for i in range(times):
                for v in range(len(temp_stack)-1, -1, -1):
                    stack.append(temp_stack[v])
            # 下标 i 跳位,跳过 <> 符号以及里面的重复次数
            i = j + 1
        else:
            stack.append(strInput[i])
            i += 1
    return "".join(stack)

valid brackets

Because the above question was not done during the interview, the interviewer was more harmonious, and gave another simple question. This question is an original LeetCode question. Fortunately, I did it, and wrote LeetCode in one breath:
20. Effective Parentheses
Code Thoughts: 20. Effective Parentheses

Given a string s consisting only of '(', ')', '{', '}', '[', ']', determine whether the string is valid.
Valid character strings must meet:
1) The opening bracket must be closed with the same type of closing bracket.
2) Opening brackets must be closed in the correct order.
Example:
input: s = "(]", output: false
input: s = "()[]{}", output: true
input: s = "([)]", output: false

Analysis:
1) Quickly judge, if the length of str is not an even number, it means that there must be a mismatch, and you can directly return False
2) Put str into the stack in turn
3) Judge whether the current character is ")", "]", " }", if it is, pop out the element in the stack, and judge whether the popped element matches the current character, if not, return False directly 4) When returning at the end, you only need to judge whether the stack
is is empty, returns True if true

Python source code

def demo(strInput):
    # 快速判断
    if len(strInput) % 2 != 0: return False
    stack = []
    str_pairs = {
    
    ')': '(', ']': '[', '}': '{'}
    for v in strInput:
        if v in str_pairs:
            # 细节问题:应该要先判断stack是否为空
            # 不然当第一个元素就为')'、']'或'}'时,程序会报错
            # 面试时候这点没有考虑到,直接判断了pop出来的元素
            if len(stack) == 0 or stack[-1] != str_pairs[v]:
                return False
            else:
                stack.pop()
        else:
            stack.append(v)
    # 细节问题:我面试的时候写的是
    # if len(stack) == 0: return True
    # else: return False
    # 这里被面试官提醒了,说这个返回太臃肿了,可以不可以简化一下
    # 结果我没说出来
    # 面试官直接说了:
    # return len(stack) == 0
    # return not stack 可能是最简洁的了,又学习了
    return not stack

byte

Byte Smart Creation

Square of sorted array

I came up with a simple question directly, but because I was too much PUA before, my head was blank, and I didn’t get AC off this question, so I felt very uncomfortable. LeetCode: 977. The square of an ordered array Random thoughts on
code :
977 . The square of an ordered array
is slightly different from the original question of LeetCode in that it is required to return non-repeating elements

Given an array of integers nums sorted in non-decreasing order, return a new array consisting of the square of each number, also sorted in non-decreasing order.
Example:
input: nums = [-5,-4,-1,0,1,3,5,5], output: [0,1,9,16,25]
input: nums = [-4,-1 ,0,3,10], output: [0,1,9,16,100]

Analysis
1) Define the first and last double pointers, that is, the left and right pointers, which point to the first element and the last element of the input array respectively 2)
Determine the square value of the elements pointed to by left and right, and put the square value of the larger pointer Enter the end of the result. Note that it must be the end, so I have to use insert. I used append directly during the interview, which directly caused me to fail this question, because my head was blank, and I didn’t find such a simple question. Then move the pointer, if it is left moves to the right, if it is right, moves to the left

Python source code

def demo(nums):
    result = []
    left, right = 0, len(nums)-1
    pre = -1 # 记录添加到result里面的最新元素,用来避免重复元素的添加
    while left <= right: # 一定要有等于,不然会漏掉一个元素
        left_square = nums[left] * nums[left]
        right_square = nums[right] * nums[right]
        if left_square >= right_square: # 取出那个较大的平方值
            if left_square != pre:
                # 注意一定是insert,而不是append!!!
                # 插入到数组的末端
                result.insert(0, left_square)
                pre = left_square
            left += 1
        else:
            if right_square != pre:
                result.insert(0, right_square)
                pre = right_square
            right -= 1
    return result

TnS Content Security Side

Phone screen unlock method

Input: m=2, n=2, s=2. m, n represents the size of the matrix, that is, m rows and n columns, s represents the number of unlocking steps, that is, several points are drawn to
output: '1->2', '1->3', '1->4', '2->1', '2->3', '2->4', '3->1', '3->2', '3->4', '4->1', ' 4->2', '4->3'

If m=2, n=2, the matrix is:
[[1, 2],
[3, 4]]
If m=3, n=3, the matrix is:
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

Analysis:
The idea of ​​this question is not difficult, and you can directly think of using backtracking.
The difficulty is to examine the code ability.
Similar questions
LeetCode: 79. Word search

Python source code

def demo(m, n, s):
    res = []
    path = []

    # 生成矩阵
    # m=2, n=2: [[1,2], [3,4]]
    # m=3,n=3: [[1,2,3], [4,5,6], [7,8,9]]
    board = [[0] * n for _ in range(m)]
    start = 1
    for i in range(m):
        for j in range(n):
            board[i][j] = start
            start += 1

    def backtracking(board, i, j):
        # 如果路径长度等于s,说明该路径已经完成,直接返回True
        if len(path) == s:
            res.append('->'.join(path))
            return True
        # 如果回溯的下标不满足矩阵的范围,就返回False
        if not (0<=i and i<m and 0<=j and j<n): return False
        # 用-1表示这个位置已经经过,就返回False
        if board[i][j] == -1: return False

        # 在path中添加当前元素
        path.append(str(board[i][j]))
        temp = board[i][j]
        # 将当前元素置为-1,表示当前元素已经经过
        board[i][j] = -1
        flag = False
        for si in range(-1, 2):
            for sj in range(-1, 2):
                if si == 0 and sj == 0: continue
                if backtracking(board, i+si, j+sj):
                    flag = True
                    break
            if flag: break
        # 弹出当前元素
        path.pop()
        # 重新归位当前元素
        board[i][j] = temp

    # 遍历所有元素,定义路径的起点
    for i in range(m):
        for j in range(n):
            backtracking(board, i, j)

    return res

print(demo(2, 2, 2))

Two sides of TnS content security

find problem

LeetCode Original Title: 33. Search Rotation Sorting Array
81. Search Rotation Sorting Array II
insert image description here
Analysis:
Core idea:
Divide the array into two, one of which must be in order, the other may be in order, or partially sequence.
At this time, the ordered part is searched by binary method. The unordered part is divided into two parts, one of which must be ordered, and the other may be ordered or disordered. Loop like this
1) Compare the middle value with the current left value, if the middle value is greater than or equal to the current left value, it means that the left side of the middle value is in order. Then judge whether the target value is in the ordered array on the left. If it is, narrow the range on the right; if not, narrow the range on the left
. Then judge whether the target value is in the ordered array on the right. If it is, narrow the range on the left; if not, narrow the range on the
right .

Python source code:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid

            if nums[mid] >= nums[left]:
                if nums[left] <= target <= nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                if nums[mid] <= target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1

        return -1

Three aspects of TnS content security

sliding window

Given a string, find the longest string without repeated characters
For example: input 'abbbcdefff', output 'bcdef'

Python source code:

def check(alphaDict):
    for key, val in alphaDict.items():
        if val > 1: return False
    return True

def demo(strInput):
    maxLen = 0
    res = ''
    left = right = 0
    alphaDict = dict()
    while right < len(strInput):
        if strInput[right] not in alphaDict: alphaDict[strInput[right]] = 1
        else: alphaDict[strInput[right]] += 1
        while not check(alphaDict):
            alphaDict[strInput[left]] -= 1
            left += 1
        tmpLen = right - left + 1
        if tmpLen > maxLen:
            maxLen = tmpLen
            res = strInput[left:right+1]
        right += 1
    return res

print(demo('abbbcdefff'))

NIO

Two sides of autonomous driving

string conversion

A question with Huawei BG

quick worker

computer vision side

Calculate IoU

meituan

Beidou - unmanned delivery vehicle side

rotating list

LeetCode original question: 61. Rotating linked list

sliding window maximum

LeetCode Original Title: 239. Maximum Sliding Window

Guess you like

Origin blog.csdn.net/qq_33757398/article/details/125814937