2020字節跳動秋招筆試題解析與代碼分享(持續更新中)

引言

2020年秋招已經結束了,小夥伴的情況如何啊。趁着過年前在家,把今年字節跳動秋招上機筆試題整理分享給大家。
在這裏插入圖片描述

1. 圓形花園的入口

題目描述
現有一個圓形花園共有 n 個入口,現在要修些路,穿過這些花園。要求每個入口只能有一條路,所有的路均不會相交,求所有可行的方法總數。
若圓形花園中有四個入口,答案2
若圓形花園中有六個入口,答案4
在這裏插入圖片描述

輸入描述
整數n,代表有n個花園入口,n爲2的倍數,n在2到1000的整數區間範圍內

輸出描述
輸出整數 m mod 1000000007,採用 mod 1000000007 降低數字量級。

**分析:**以n = 8爲例,之前的n = 6,4,2,0的情況都已經知道了。8是在6的基礎上添加了兩個點,例如把1,2連接在一起,剩下的就是6個點連接方式就是dp[ 6 ],1還可以連接哪些點呢?3是不可以的,因爲要求直線不可以相交,1,3相連之後,2就被包圍了,所以2的直線就肯定和別的直線相交。換句話說,從1開始和另外一個點把剩下的6個點分割成兩個部分,這兩部分只能內部連接,所以兩部分的點數都必須是偶數。思路進一步等價=>遍歷所有和等於6並且各自點數爲偶數(包括0)的情況,又因爲兩個部分各自獨立,所以總的情況等於兩部分情況之積。所有的積之和就是當前的 dp[ 8 ]。推廣到一般形式:8->n,6->n-2。

另外不用考慮不同的起點問題,以單一起點已經考慮了所有的情況,其他點作爲起點的情況也被考慮在內了。

代碼實現:
Python:

if __name__ == "__main__":
    n = int(input())
    res = [0]*(n+1)
    res[0] = 1
    for i in range(2, n+1, 2):
        for j in range(0, (i-2)+1, 2):
            res[i] += (res[j]*res[i-2-j])
        res[i] = res[i] % 1000000007
    print(res[n])

這一類題型爲 卡特蘭數,leetcode 96題,AC 100%

C++:

在這裏插入代碼片

2. 2048合併

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
題目分析:

代碼實現:

3. 得到更多糖果


在這裏插入圖片描述

題目分析:

代碼實現:

4. 世界盃開幕式

思路:跟leetcode上求島嶼數量問題很像,使用DFS,這裏要注意的是搜索方向從4個變成了8個,並且要輸出最大區域裏的人數。

代碼實現: 引自Cytues - 1. 世界盃開幕式

# coding:utf-8
M, N = list(map(int, raw_input().split(',')))
 
book = []
 
for i in range(M):
    line = list(map(int, raw_input().split(',')))
    book.append(line)
 
class Solution:
    def __init__(self, grid):
        self.grid = grid
        # 當前區域的人數
        self.cnt = 0
        # 保存所有區域中的人數,返回其長度,及其最大值
        self.dp = []
 
    def dfs(self, i, j):
        if 0 <= i < M and 0 <= j < N:
            if self.grid[i][j] == 1:
                self.cnt += 1
                # 經過的點就置0
                self.grid[i][j] = 0
                # (i-1,j-1) (i-1,j) (i-1,j+1)
                # (i,j-1)   (i,j)   (i,j+1)
                # (i+1,j-1) (i+1,j) (i+1,j+1)
                # 8個方向搜索
                self.dfs(i - 1, j)
                self.dfs(i + 1, j)
                self.dfs(i, j - 1)
                self.dfs(i, j + 1)
                self.dfs(i - 1, j - 1)
                self.dfs(i + 1, j + 1)
                self.dfs(i + 1, j - 1)
                self.dfs(i - 1, j + 1)
 
    def solve(self):
        for i in range(M):
            for j in range(N):
                if self.grid[i][j] == 1:
                    # 每找到一個新區域就清0,因爲被搜索過的1都置0了,所以新區還是1
                    self.cnt = 0
                    self.dfs(i, j)
                    if self.cnt > 0:
                        self.dp.append(self.cnt)
 
        return len(self.dp), max(self.dp)

5. 文章病句標識

思路

  • 區間合併
  • 排序 + 貪心
    對 [l1,r1], [l2,r2],如果 r1 > l2,則 r1 = max(r1, r2)

代碼實現: 引自Cytues - 2. 文章病句標識

# coding:utf-8
m = int(raw_input())
temp = []
 
for _ in range(m):
    line = [list(map(int, item.split(','))) for item in raw_input().split(';')]
    # [[1, 10], [32, 45]]
    temp.extend(line)
 
# 按每段病句[l, r]的第一個位置l排序
temp = sorted(temp, key=lambda x: x[0])
 
# [[1, 10]]
ret = [temp[0]]
 
# 與之後的病句段進行比較
for item in temp[1:]:
 
    # res[-1][1] == 10從後往前取
    # item == [32, 45], item[0] == 32
    if ret[-1][1] >= item[0]:
        # 貪心:對 [l1,r1], [l2,r2],如果 r1 > l2,則 r1 = max(r1, r2)
        # [5, 16], [16, 32], 16 >= 16, max(16, 32) ---> [5, 32]
        ret[-1][1] = max(ret[-1][1], item[1])
    else:
        # [[1, 10], [32, 45]]
        ret.append(item)
 
s = ''
 
# 不取最後一位,因爲最後一位末尾不添加分號
for item in ret[:-1]:
    s += str(item[0]) + ',' + str(item[1]) + ';'
 
# 單獨處理
s += str(ret[-1][0]) + ',' + str(ret[-1][1])
 
print s

6. 積分卡牌遊戲

思路

  • 動態規劃
  • DP 定義:d[i][j]​ := 前 i 張牌,兩人所選擇的牌的差值爲 j 時的最大值
  • 轉移方程
    ​d[i][j] = max(d[i-1][j], d[i-1][j-x[i]] + y[i], d[i-1][j+x[i]] + y[i])​

代碼實現: 引自Cytues - 3. 積分卡牌遊戲

# coding:utf-8
n = int(raw_input())
x, y = [], []
 
for i in range(n):
    _x, _y = list(map(int, raw_input().split()))
    x.append(_x)
    y.append(_y)
 
xy = list(zip(x, y))
# print xy
# 根據y的值進行排序
xy = sorted(xy, key=lambda t: t[1])
# print xy
 
ret = 0
# 如果所有 x 的和爲偶數
# 直接輸出所有 y 的和
if sum(x) % 2 == 0:
    print sum(y)
else:
    for i in range(len(xy)):
        if xy[i][0] % 2 == 1:
            # j只取偶數,排除掉x中的奇數項
            ret = sum([xy[j][1] for j in range(len(xy)) if j != i])
            print ret
            break

思路: leetcode原題

代碼實現:

N = int(raw_input())
line = list(map(int, raw_input().split()))
 
count = 0
 
for i in line:
    if count == 0:
        if i >> 3 == 0b11110:
            count = 3
        elif i >> 4 == 0b1110:
            count = 2
        elif i >> 5 == 0b110:
            count = 1
        elif i >> 7 == 0b0:
            count = 0
        else:
            print 0
    else:
        if i >> 6 == 0b10:
            count -= 1
        else:
            print 0
 
print 1


上一篇:從瀏覽器輸入一個URL(www.baidu.com)後執行全過程

下一篇:TCP三次握手、四次揮手幾常見面試題全集


歡迎各位訂閱我,謝謝大家的點贊和專注!我會繼續給大家分享我大學期間詳細的實踐項目。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章