首页 > 其他分享 >谷歌(Google)技术面试概述

谷歌(Google)技术面试概述

时间:2024-04-04 09:01:58浏览次数:17  
标签:Google 数字 谷歌 面试 p1 grid 数组 nums1 nums2

概述

谷歌(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':
            return
        grid[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 0
    
    num_islands = 0
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == '1': # 如果是陆地,则进行深度优先搜索
                num_islands += 1
                dfs(grid, i, j)
    
    return num_islands

这个函数首先定义了一个辅助函数 dfs(),用于深度优先搜索并将访问过的陆地标记为 ‘0’,然后遍历整个网格,对每个未访问过的陆地进行深度优先搜索,计算岛屿的数量。

2.广度优先搜索(BFS)

除了深度优先搜索(DFS)之外,还可以使用广度优先搜索(BFS)来解决这个问题:

from collections import deque

def 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':
                continue
            grid[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 0
    
    num_islands = 0
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == '1': # 如果是陆地,则进行广度优先搜索
                num_islands += 1
                bfs(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 Counter

def 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 类统计了 nums1nums2 中各数字出现的次数。然后遍历 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 += 1
            p2 += 1
        elif nums1[p1] < nums2[p2]:
            # 如果 nums1[p1] < nums2[p2],则将 p1 向后移动一位
            p1 += 1
        else:
            # 如果 nums1[p1] > nums2[p2],则将 p2 向后移动一位
            p2 += 1
    
    return result

这个函数首先对两个数组进行排序,然后初始化两个指针指向数组的起始位置。然后循环比较两个数组中的数字,如果两个数字相等,则将该数字添加到结果列表中,并将两个指针都向后移动一位;如果不相等,则将较小的数字所在的指针向后移动一位。最后返回结果列表。

标签:Google,数字,谷歌,面试,p1,grid,数组,nums1,nums2
From: https://blog.csdn.net/SmiledrinkCat/article/details/137286026

相关文章

  • 谷歌(Google)技术面试——在线评估问题(一)
    谷歌(Google)面试过程的第一步,你可能会收到一个在线评估链接。评估有效期为7天,包含两个编码问题,需要在一小时内完成。以下是一些供你练习的在线评估问题。在本章结尾处,还提供了有关Google面试不同阶段的更多详细信息。重复叠加字符串匹配给定两个字符串a和b,寻找重......
  • 常见面试题--动态规划介绍(附C++源码实现)
    关注我,持续分享逻辑思维&管理思维;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;有意找工作的同学,请参考博主的原创:《面试官心得--面试前应该如何准备》,《面试官心得--面试时如何进行自我介绍》, 《做好面试准备,迎接2024金三银四》。【图解《程序员面试常见的十大算法......
  • Java最短路径算法知识点(含面试大厂题和源码)
    最短路径算法是计算机科学和图论中的核心问题之一,它旨在找到从一个顶点到另一个顶点或在所有顶点之间的最短路径。这个问题在多种实际应用中都非常重要,如网络路由、交通规划、社交网络分析等。以下是一些与最短路径算法相关的知识点:Dijkstra算法:由荷兰计算机科学家艾兹......
  • Java归并排序知识点(含面试大厂题和源码)
    归并排序是一种有效的排序算法,采用分治法(DivideandConquer)策略。它将数组分成两半,对每一半递归地进行排序,然后将两个有序的半部分合并成一个整体的有序数组。归并排序在最坏情况、平均情况和最好情况下都保持(O(n\logn))的时间复杂度,是一种稳定的排序算法。由于其分而治......
  • Java快速排序知识点(含面试大厂题含源码)
    快速排序是一种高效的排序算法,由C.A.R.Hoare在1960年提出。它的基本思想是分而治之(DivideandConquer)。快速排序的关键在于选取一个“基准值”(pivot),然后将数组分为两个子数组:一个包含所有小于基准值的元素,另一个包含所有大于基准值的元素。这个过程称为“分区”(partitio......
  • Java后端新手的第一次面试复盘
    昨天经历了第一次Java后端实习生面试,在无数次的简历投递后,很难得的一次面试机会,收获很多,也深刻感受到自己能力的不足(还需要继续沉淀半个学期),在此记录下收获和感悟,如有错误,欢迎指正!1.面试流程闲聊(5分钟):自我介绍+询问背景动机技术问答(45分钟):包括Java基础、数据库技......
  • 面试题总结综合
    煞笔!终究转移到这是吗?1.自我介绍你好我叫杨凯23年毕业于河北工业大学211计算机科学与技术专业这次应聘的是贵公司测试工程师的(Java后端研发工程师的)岗位大学期间参加过创新创业大赛以及acm的培训(有两年的开发经验,其中一年在实习)做过的项目有实习时做的接口管理......
  • 面试常问问题——关于常用sql查询语句
    1、select--第一种select*from表名称--第二种select列名称from表名称2、select DISTINCT 去重SELECTDISTINCT列名称FROM表名称3、where子句1--第一种2SELECT列名称FROM表名称WHERE列运算符值34--第二种5SELECT*FROM表名称WHER......
  • 【Redis】.Net Core 面试破冰
    目录1.Redis简介2.使用场景3.C#具体使用介绍(Nuget)StackExchange.RedisFreeRedisNewLife.RedisServiceStack.Redis(收费)4.Redis常用面试问题以及回答5.建议及经验分享建议Redis经验分享ShareFlow1.Redis简介Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持......
  • http前端面试题
    http状态码状态码分类1xx服务器收到请求2xx成功3xx重定向4xx客户端错误5xx服务器错误常见状态码http协议中的状态码有很多,但只有一些是我们常用的。也是面试常考的。200成功301永久重定向(同时返回一个location,写明重定向的url)。例如一个网站的网址永久性的切换......