今日头条研发算法岗实习生笔试题解答篇_0324晚

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a786150017/article/details/79689754

python实现,个人理解和总结。有错误烦请指正,感谢!!
C++版参见牛客

1.数组中差为K的数对

题目: 给定n个数,k是差值,计算非重复数字对的个数。

第一行输入n,k; 第二行输入n个数

解法: leetcode532

法1:nums中每个元素+k, 得到新数组new, set(nums)和set(new)取交集

法2:
(1)和法1类似,建立一个dic存储nums中元素出现的个数;
(2)然后遍历哈希表中的数字, 如果k为0且该数字出现的次数大于1,则结果res自增1;
(3)如果k不为0,且用当前数字加上k后得到的新数字也在数组中存在,则结果res自增1

法3:时间换空间。给数组排序,然后使用双指针。遍历排序后的数组,然后在当前数字之后找第一个和当前数之差不小于k的数字,若这个数字和当前数字之差正好为k,那么结果res自增1,然后遍历后面的数字去掉重复数字。

代码:

def findPairs1(nums, k): 
    new = [num+k for num in nums]
    return len(set(nums)&set(new))
def findPairs2(nums, k): 
    dic = {}
    for num in nums:
        if num in dic:
            dic[num] += 1
        else:
            dic[num] = 1

    res = 0
    for num in dic:
        if k == 0 and dic[num] > 1:
            res += 1
        elif k > 0 and num + k in dic:
            res += 1
    return res
def findPairs3(nums, k):
    res = 0
    nums.sort()
    i = 0
    while i < len(nums):
        j = i+1    # i后面的第一个数
        while j < len(nums) and  nums[j] - nums[i] < k:    # 找到第一个和当前数之差≥k的数字
            j += 1
        if j < len(nums) and nums[j] - nums[i] == k:
            res += 1
        while i < len(nums)-1 and nums[i] == nums[i+1]:  # 去重
            i += 1
        i += 1
    return res

2.求函数调用次数

题目: 定义两个字符串变量:s和m,再定义两种操作:

① m = s; s = s + s; ② s = s + m

假设s初始化如下:s = “a”, m = s;

求最小的操作步骤数, 可以将s拼接到长度等于n。

示例:

输入6,输出3;输入5,输出4;输入7,输出6;输入9,输出4。

解法:

法1:(递归)从头开始考虑选用①或②

法2:(BFS)模拟层次遍历,每一步两条路走

法3(DP):leetcode650变形

可以转换为 ① m = s; s = s + m; ② s = s + m ——> 复制操作m=s和粘贴操作s=s+m

??不懂哎

代码:

def get_minpot(s,m,n):
    cnt = 0
    # 截止条件
    if s == n:
        return cnt
    if s > n:
        return n
    return min(get_minpot(s*2,s,n), get_minpot(s+m,m,n)) + 1
def countStep1(n):
    return get_minpot(1,1,n)
def countStep2(n):
    step = 0
    queue = [(1,1,step)]    # 初始化为(s,m)

    while queue:
        size = len(queue)
        for i in range(size):
            temp = queue.pop(0)
            if temp[0] == n:
                return step
            # 采用①
            if temp[0]*2 <= n:
                queue.append((temp[0]*2,temp[0]))
            # 采用②
            if temp[0] + temp[1] <= n:
                queue.append((temp[0] + temp[1],temp[1]))      
        step += 1  # 每遍历一层,步数+1

3. 输出666

代码:

nn = [
[
'66666',
'6...6',
'6...6',
'6...6',
'66666'
],[
'....6',
'....6',
'....6',
'....6',
'....6'
],[
'66666',
'....6',
'66666',
'6....',
'66666'
],[
'66666',
'....6',
'66666',
'....6',
'66666'
],[
'6...6',
'6...6',
'66666',
'....6',
'....6'
],[
'66666',
'6....',
'66666',
'....6',
'66666'
],[
'66666',
'6....',
'66666',
'6...6',
'66666'
],[
'66666',
'....6',
'....6',
'....6',
'....6'
],[
'66666',
'6...6',
'66666',
'6...6',
'66666'
],[
'66666',
'6...6',
'66666',
'....6',
'66666'
]
]

if __name__ == '__main__':
    n = int(input())
    for _ in range(n):
        s = input()  # 比如输入6+6
        s = str(eval(s))  # 求得s='12'

        ans = [[] for _ in range(5)]  # 输出5for i in s:
            x = int(i)
            ans[0].append(nn[x][0])
            ans[1].append(nn[x][1])
            ans[2].append(nn[x][2])
            ans[3].append(nn[x][3])
            ans[4].append(nn[x][4])
        for i in range(5):
            print('..'.join(ans[i]))

4.Magic

解法:

都排序,比较平均值大小,均值大A的往均值小的B放数(数a大于B均值,且小于A均值)

代码:

def magic(A, B):
    A = sorted(A)
    B = sorted(B)
    if sum(set(A))/len(A) < sum(set(B))/len(B):
        A, B = B, A
    cnt = 0    
    av_A = sum(set(A))/len(A)
    av_B = sum(set(B))/len(B)

    for i in range(len(A)):
        if len(A) <= 1:
            return cnt
        if A[i] > av_B and A[i] < av_A:
            B = set(B)
            B.add(A[i])
            A.pop(i)

            print('A:',A)
            print('B:',B)
            cnt += magic(A, B)+1
            break

    return cnt

5.跳板游戏

题目: 已知空中有N个高度不同的跳板,小T刚开始在高度为0的地方,每次跳跃可以选择和直接当前..

解法:

注意:不一定每次都要贪心选最好的跳板

比如1 3 4 6,h=2,贪心只能0-2-6,而实际上可以0-2-4-8

解法:每层都存储跳1,2..H高度的结果,层次遍历

代码:

# (×)考虑不周全的代码
N = [1,3,6]
K = 3  # K次
H = 2  # 高度差

start = 0
N.sort()
for _ in range(K):
    for i in range(len(N)):
        if N[i] - start > H or len(N) == 1 and N[i] - start <= H:  # 找到第一个大于的
            start = 2 * N[i-1] - start
            N.pop(i-1)
            break
print(start)
# 参照牛客改的Python版,跑起来好慢...
N = [1,3,6]
K = 4  # K次
H = 2  # 高度差

vis = [0] * int(1e8)
# 建立一个稀疏向量,存储台阶的位置
a = [0] * int(1e8)
for n in N:
    a[n] = 1

start = 0
step= 0
q = [(start,step)]  # (位置,到该位置要跳多少下)

res = 0  # 高度
while q:
    start, step = q.pop(0)
    if step > K:  # 此处判断>K,是想让K次的最高位置都保存了
        break

    if start > res:
        res = start
    for h in range(1,H+1):  # 一次跳多高
        # 位置有跳板,&可以跳到未被访问的位置
        if a[start+h] and not vis[start+2*h]:
            vis[start+2*h] = True  # 之前跳到过这个位置,不用再存储了
            q.append((start+2*h,step+1))
         # 5,10,11  H=6,K=4可以回跳,最高可以到14   
        if start-2*h>0 and a[start-h] and not vis[start-2*h]:
            vis[start+2*h] = True  # 之前跳到过这个位置,不用再存储了
            q.append((start-2*h,step+1))
print(res)    

猜你喜欢

转载自blog.csdn.net/a786150017/article/details/79689754