概述
谷歌(Google)技术面试非常困难而且富有挑战性。想要获得电话面试,你需要将简历提交到他们的在线申请系统或者通过内部员工进行推荐。
假设你通过了简历审阅,招聘人员会联系你。通常情况下会有两次电话面试,如果表现优秀,你将会获邀参与现场面试.
由于谷歌业务往往涉及大规模应用场景,请准备好回答关于如何扩展为多台机器编写的算法的大量后续问题。例如:岛屿的个数、两个数组的交集 II。
一、岛屿的个数
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
[“1”,“1”,“1”,“1”,“0”],
[“1”,“1”,“0”,“1”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“0”,“0”,“0”]
]
输出:1示例 2:
输入:grid = [
[“1”,“1”,“0”,“0”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“1”,“0”,“0”],
[“0”,“0”,“0”,“1”,“1”]
]
输出:3
1.深度优先搜索(DFS)
我们可以使用深度优先搜索(DFS)来解决这个问题:
def numIslands(grid):def dfs(grid, i, j):if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] == '0':returngrid[i][j] = '0' # 将访问过的陆地标记为 '0'dfs(grid, i+1, j) # 上下左右进行深度优先搜索dfs(grid, i-1, j)dfs(grid, i, j+1)dfs(grid, i, j-1)if not grid:return 0num_islands = 0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j] == '1': # 如果是陆地,则进行深度优先搜索num_islands += 1dfs(grid, i, j)return num_islands
这个函数首先定义了一个辅助函数 dfs()
,用于深度优先搜索并将访问过的陆地标记为 ‘0’,然后遍历整个网格,对每个未访问过的陆地进行深度优先搜索,计算岛屿的数量。
2.广度优先搜索(BFS)
除了深度优先搜索(DFS)之外,还可以使用广度优先搜索(BFS)来解决这个问题:
from collections import dequedef numIslands(grid):def bfs(grid, i, j):queue = deque([(i, j)])while queue:x, y = queue.popleft()if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] == '0':continuegrid[x][y] = '0' # 将访问过的陆地标记为 '0'queue.append((x+1, y)) # 将上下左右未访问过的陆地加入队列queue.append((x-1, y))queue.append((x, y+1))queue.append((x, y-1))if not grid:return 0num_islands = 0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j] == '1': # 如果是陆地,则进行广度优先搜索num_islands += 1bfs(grid, i, j)return num_islands
这个函数首先定义了一个辅助函数 bfs()
,用于广度优先搜索并将访问过的陆地标记为 ‘0’,然后遍历整个网格,对每个未访问过的陆地进行广度优先搜索,计算岛屿的数量。
二、两个数组的交集 II
给你两个整数数组 nums1 和 nums2,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]提示:
1 <= nums1.length, nums2.length <= 1000 0 <= nums1[i], nums2[i] <=1000
1.哈希表
首先,我们可以使用哈希表来解决这个问题。遍历一个数组,用哈希表记录每个数字出现的次数,然后遍历另一个数组,检查其中的数字在哈希表中是否存在,如果存在,则将该数字添加到结果列表中,并减少哈希表中该数字的计数。
from collections import Counterdef intersect(nums1, nums2):# 统计 nums1 和 nums2 中各数字出现的次数counter1 = Counter(nums1)counter2 = Counter(nums2)# 初始化结果列表result = []# 遍历哈希表 counter1 中的键值对for num, count in counter1.items():# 检查当前数字在 counter2 中是否存在if num in counter2:# 如果存在,则将该数字添加到结果列表中,次数取较小值result.extend([num] * min(count, counter2[num]))return result
这个函数首先利用 Counter
类统计了 nums1
和 nums2
中各数字出现的次数。然后遍历 counter1
中的键值对,检查当前数字在 counter2
中是否存在,如果存在,则将该数字添加到结果列表中,次数取较小值。最后返回结果列表。
2.双指针
除了使用哈希表之外,还可以使用双指针来解决这个问题。首先对两个数组进行排序,然后使用两个指针分别指向两个数组的起始位置,比较两个指针指向的数字,如果相等,则将该数字添加到结果列表中,并将两个指针都向后移动一位;如果不相等,则将较小的数字所在的指针向后移动一位。重复这个过程直到某个指针达到数组末尾。
def intersect(nums1, nums2):# 对两个数组进行排序nums1.sort()nums2.sort()# 初始化结果列表和双指针result = []p1, p2 = 0, 0# 循环比较两个数组中的数字while p1 < len(nums1) and p2 < len(nums2):if nums1[p1] == nums2[p2]:# 如果两个数字相等,则将该数字添加到结果列表中,并将两个指针都向后移动一位result.append(nums1[p1])p1 += 1p2 += 1elif nums1[p1] < nums2[p2]:# 如果 nums1[p1] < nums2[p2],则将 p1 向后移动一位p1 += 1else:# 如果 nums1[p1] > nums2[p2],则将 p2 向后移动一位p2 += 1return result
这个函数首先对两个数组进行排序,然后初始化两个指针指向数组的起始位置。然后循环比较两个数组中的数字,如果两个数字相等,则将该数字添加到结果列表中,并将两个指针都向后移动一位;如果不相等,则将较小的数字所在的指针向后移动一位。最后返回结果列表。
谷歌(Google)技术面试系列
- 谷歌(Google)历年编程真题——数组和字符串(螺旋矩阵)
- 谷歌(Google)历年编程真题——数组和字符串(加一)
- 谷歌(Google)技术面试——在线评估问题(一)
- 谷歌(Google)技术面试——在线评估问题(二)
- 谷歌(Google)技术面试——在线评估问题(三)
- 谷歌(Google)技术面试——在线评估问题(四)
- 谷歌(Google)技术面试——全部面试流程