春招第一个算法笔试 北京博***有限公司 游戏开发
已经很久没碰算法了,对我来说这个笔试题非常之难,没有100%通过的题
1.一组字符串类似下面:
判断每个字符串是否都能通过一个轨迹得到
现在来看其实非常简单,只需要不断递归,每次向四个方向查找,如果是下一个字符,就继续递归,否则返回false,直到四个三个方向都返回false或者找到整个字符串
输入:
map = [
['a', 'b', 'c', 'e'],
['s', 'f', 'c', 's'],
['a', 'd', 'e', 'e']
]
strArr = ["abc", "ass", "bad", "see", "fcs"]
返回:[True, False, False, True, True]
实现代码参考:
from typing import List
class Solution:
def findWords(self, map: List[List[str]], strArr: List[str]) -> List[bool]:
row = len(map)
col = len(map[0])
visited = [[False]*col for _ in range(row)]
def find_index(i, j, index, word):
if len(word) <= index:
return True
if i < 0 or i >= row or j < 0 or j >= col \
or visited[i][j] or map[i][j] != word[index]:
return False
# 当前元素等于word[index],遍历寻找下一个
visited[i][j] = True
found = find_index(i-1, j , index + 1, word) or \
find_index(i+1, j , index + 1, word) or \
find_index(i, j-1, index + 1, word) or \
find_index(i, j+1, index + 1, word)
visited[i][j] = False
print(found)
return found
re = []
for word in strArr:
if len(word) == 0:
re.append(False)
continue
found = False
for i in range(row):
for j in range(col):
if map[i][j] == word[0]:
found = find_index(i, j, 0, word) or found
re.append(found)
return re
if __name__=="__main__":
map = [
['a', 'b', 'c', 'e'],
['s', 'f', 'c', 's'],
['a', 'd', 'e', 'e']
]
strArr = ["abc", "sad", "saf", "fcd"]
re = Solution().findWords(map, strArr)
print(re)
2.考察给一个整数n,判断所有从[1,n]的整数中字符1-9出现的次数
当时给我整蒙了,后来问deepseek搞明白了,其实思路也挺简单,就是每一次只判断某一位出现某个数的次数
比如:先算从[1-n] 所有整数的个位出现1的次数,很容易,比如 51000就出现5101次,然后依次计算出现2、3...,十位百位
参考代码:
from typing import List
class Solution:
def CountNumber(self, n:int) -> List[int]:
result = [0]*10
def count_one_number(digtal, n):
i = 1
while i <= n: # 注意这里是<= ,如果是< ,当最高位为1是会漏掉一个1
driver = i*10 # 用来分割位数,将数字分割为 high, cover, low
high = n // driver
cover = (n //i)% 10
low = n % i
# 单独处理0
if digtal == 0:
if high == 0:
# 高位为0,当前数是前导0,不机算
i *= 10
continue
if cover == 0:
# 当前位为0, 高位有 high个值可选(比如high=2时,可选1,2),但是高位不变时,低位只有 low+1 个值可选
result[digtal] += (high-1) * i + (low + 1)
elif cover > 0:
# 高位 有high个值可选,低位所有值可选
result[digtal] += high * i
else:
# 当前位不为0时
if cover == digtal:
# 当前位于digtal一致,高位有 high+1个值可选(包括0), 当高位为0时,低位只有low+1个值可选
result[digtal] += high*i + (low + 1)
elif cover > digtal:
# 当前位大于digtal,高位有 high+1个值可选(包括0)
result[digtal] += (high+1) * i
else:
# 当前位小于digtal,高位只有high个值可选(0不行)
result[digtal] += high * i
# 处理完当前位,处理下一位
i *= 10
for i in range(10):
count_one_number(i, n)
return result
if __name__=="__main__":
re = Solution().CountNumber(100000)
print(re)
3.写希尔排序,给出移动的次数
这个以前应该也没接触过,接触过也早忘了,待会学一下
学成归来,感觉好简单:- _ - 等啥时候常见的排序算法都得重新学习一下
from typing import List
class Solution:
def shell_sort(self, numlist: List[int], gaplist: List[int]) -> int:
count = 0
for gap in gaplist:
for i in range(gap, len(numlist)):
j = i # j表示当前需要决定的位置(若temp大于前一个值就将temp插入这里,否则后移前一个元素,判断更前面一个)
temp = numlist[j]
while j >= gap and temp < numlist[j-gap]:
numlist[j] = numlist[j - gap]
j -= gap
count += 1
numlist[j] = temp
return count
if __name__ == "__main__":
sol = Solution()
arr = [9, 8, 7, 6, 5, 4, 3, 2, 1,10,11,5,2,3,6,2,1,6,11]
gaps = [4, 2, 1]
print("初始数组:", arr)
moves = sol.shell_sort(arr, gaps)
print("\n最终排序结果:", arr)
print("总移动次数:", moves)
4.划船,多少次能划到岸边,描述是第一次能划x米,然后休息,倒退y米,每一次休息都减少下一次1/5的移动距离,判断划几次能到m米的岸边
这个刚写的时候给我搞出等比数列去了,我以为会上很大的数,其实这么简单就过了
正确代码参考:
from typing import List
class Solution:
def HuaChuang(self, x:float, y: float, m:float) -> List[int]:
now_x = x
total = 0
count = 0
while total < m:
if now_x <= y:
return -1
total = total + now_x - y
now_x *= 0.8
count += 1
return count
if __name__=="__main__":
re = Solution().HuaChuang(10900,2,39900)
print(re)
第一次写的代码:
等有时间看看哪里错了
from math import log, pow
class Solution:
def max_len(self, x: float, y: float, n: int) -> bool:
sum_ = x*(1 - pow(0.8, n))/(0.2) - y*n
return sum_
def rowTheBoat(self , x: float, y: float, m: float) -> int:
# 没x米休息一次,每次休息退行y米,起始距离为m米,问最终能到达终点吗
# l1 = x - y
# l2 = x*(4/5) - y
# l3 = x*(4/5)^2 - y
# l4 = x*(4/5)^3 - y
# ...
# l_last = x*(4/5)^n - y = 0
# y = x*(4/5)^n
n = log(y/x, 0.8)
n = int(n)
# sum = l1 + l2 + l3 + ... + l_last = x*(1 + (4/5) + (4/5)^2 + ... + (4/5)^n) - y*n
# sum = x*(1 - pow(0.8, n + 1))/(0.2) - y*n
sum = self.max_len(x, y, n)
if sum < m:
# 判断再来一次是否可以
if sum + x*(0.8**(n)) + x*(0.8**(n)) >= m:
return n + 1
else:
return -1
while self.max_len(x, y, n) >= m:
n = n // 2
while self.max_len(x, y, n) < m:
n = n + 1
return n
25年春招笔试面试记录 文章被收录于专栏
记录一下春招的笔面试
