【笔试刷题】虾皮-2025.11.02-改编真题

✅ 秋招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题
  • 对照解析查漏补缺

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力

🌸 目前本专栏已经上线180+套真题改编解析,后续会持续更新的

春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗

虾皮-2025.11.02

题目一:连续序列区间表示

1️⃣:解析输入字符串,提取所有整数到数组

2️⃣:使用双指针扫描数组,找出所有连续区间

3️⃣:根据区间长度决定输出格式(单个数字或区间表示)

难度:简单

题目二:城堡探险可达性统计

1️⃣:解析输入获取二维网格,将其扁平化为一维数组

2️⃣:从入口位置开始进行 BFS 搜索,标记所有可达的空地

3️⃣:用总方格数减去可达方格数得到答案

难度:中等

题目三:网络拓扑染色检测

1️⃣:解析输入构建无向图的邻接表

2️⃣:使用 DFS 对图进行二分染色

3️⃣:检测染色过程中是否出现冲突,判断是否为二分图

难度:中等

1. 连续序列区间表示

问题描述

K 小姐在整理她的图书馆藏书编号时,发现有些书籍的编号是连续的,有些则不连续。为了便于管理,她想要用一种简洁的方式来表示这些编号。

具体来说,如果几个编号是连续的(相邻编号差为 1),就用区间 "" 来表示(例如 "" 表示编号 2、3、4、5);如果某个编号是孤立的,就单独列出这个编号(例如 "")。

现在给定一个按升序排列的、没有重复元素的书籍编号列表,请帮 K 小姐将其转换为区间表示形式。

输入格式

一行,包含一个用方括号 [] 包围、逗号分隔的整数数组,数组中的整数已按升序排列且无重复元素。

输出格式

一行,输出一个字符串数组,每个元素要么是一个区间表示(形如 ""),要么是一个单独的数字。输出格式为用方括号 [] 包围、逗号分隔的形式。

样例输入

[0,1,2,8,9,11]
[-4,-3,0,1,4,5,7]

样例输出

[0->2,8->9,11]
[-4->-3,0->1,4->5,7]
样例 解释说明
样例1 编号 0、1、2 是连续的,表示为 ;编号 8、9 是连续的,表示为 ;编号 11 是孤立的,单独列出
样例2 编号 -4、-3 连续表示为 ;编号 0、1 连续表示为 ;编号 4、5 连续表示为 ;编号 7 孤立单独列出

数据范围

  • 数组元素值

  • 数组长度

题解

这道题要求把一个有序数组中的连续元素区间化表示。核心思路很简单:从左到右扫描数组,找出每一段连续的区间。

首先需要解决输入问题。输入是一个类似 JSON 格式的数组字符串,需要提取其中的所有整数。可以把所有的方括号和逗号替换成空格,然后用字符串流或者 split 函数提取所有数字。

接下来是主要算法部分。用双指针的思想:对于每个位置 ,记录当前区间的起点 ,然后不断向后扩展,只要 ,就说明还是连续的,继续扩展并更新 。当无法继续扩展时,记录终点

判断输出格式:如果 ,说明这是一个孤立的数字,直接输出 ;否则输出区间 ""。每个区间或数字之间用逗号分隔,最外层用方括号包围。

时间复杂度分析:每个元素最多被访问一次,因此时间复杂度为 ,其中 是数组长度。对于题目的数据范围(),这个复杂度完全可以接受。

需要注意的细节:

  1. 负数的处理要正确
  2. 输出格式中逗号的位置(最后一个元素后面不加逗号)
  3. 边界情况,比如数组只有一个元素,或者所有元素都连续

参考代码

  • Python
import sys
input = lambda: sys.stdin.readline().strip()

# 读入整行
line = input()

# 提取所有数字(包括负数)
nums = []
i = 0
while i < len(line):
    if line[i].isdigit() or line[i] == '-':
        j = i
        if line[i] == '-':
            i += 1
        while i < len(line) and line[i].isdigit():
            i += 1
        nums.append(int(line[j:i]))
    else:
        i += 1

# 构建结果
res = []
i = 0
n = len(nums)
while i < n:
    start = nums[i]  # 区间起点
    end = start  # 区间终点
    # 向后扩展连续区间
    while i + 1 < n and nums[i + 1] == nums[i] + 1:
        i += 1
        end = nums[i]
    # 根据起点和终点是否相同决定输出格式
    if start == end:
        res.append(str(start))
    else:
        res.append(f"{start}->{end}")
    i += 1

# 输出结果
print('[' + ','.join(res) + ']')
  • Cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    string line;
    getline(cin, line);
    
    // 提取所有整数
    vector<int> nums;
    int i = 0, len = line.size();
    while (i < len) {
        if (isdigit(line[i]) || line[i] == '-') {
            int j = i;
            if (line[i] == '-') i++;
            while (i < len && isdigit(line[i])) i++;
            nums.push_back(stoi(line.substr(j, i - j)));
        } else {
            i++;
        }
    }
    
    // 构建区间表示
    string ans = "[";
    int n = nums.size();
    for (int i = 0; i < n; i++) {
        int st = nums[i];  // 区间起点
        int ed = st;  // 区间终点
        // 向后扩展连续区间
        while (i + 1 < n && nums[i + 1] == nums[i] + 1) {
            i++;
            ed = nums[i];
        }
        // 根据起点和终点决定输出格式
        if (st == ed) {
            ans += to_string(st);
        } else {
            ans += to_string(st) + "->" + to_string(ed);
        }
        // 如果不是最后一个元素,添加逗号
        if (i < n - 1) ans += ",";
    }
    ans += "]";
    
    cout << ans << endl;
    return 0;
}
  • Java
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        
        // 提取所有整数
        List<Integer> nums = new ArrayList<>();
        int i = 0, len = line.length();
        while (i < len) {
            if (Character.isDigit(line.charAt(i)) || line.charAt(i) == '-') {
                int j = i;
                if (line.charAt(i) == '-') i++;
                while (i < len && Character.isDigit(line.charAt(i))) i++;
                nums.add(Integer.parseInt(line.substring(j, i)));
            } else {
                i++;
            }
        }
        
        // 构建区间表示
        StringBuilder sb = new StringBuilder("[");
        int n = nums.size();
        for (i = 0; i < n; i++) {
            int start = nums.get(i);  // 区间起点
            int end = start;  // 区间终点
            // 向后扩展连续区间
            while (i + 1 < n && nums.get(i + 1) == nums.get(i) + 1) {
                i++;
                end = nums.get(i);
            }
            // 根据起点和终点决定输出格式
            if (start == end) {
                sb.append(start);
            } else {
                sb.append(start).append("->").append(end);
            }
            // 如果不是最后一个元素,添加逗号
            if (i < n - 1) sb.append(",");
        }
        sb.append("]");
        
        System.out.println(sb.toString());
    }
}

2. 城堡探险可达性统计

问题描述

A 先生正在开发一款探险类游戏。游戏中有一座古老的城堡,城堡的地图可以用一个 的方格网络表示。每个方格要么是可以通行的空地(用 表示),要么是无法通过的墙壁(用 表示)。

玩家从城堡的入口(坐标 )开始探险,只能沿着上、下、左、右四个方向在空地上移动,不能穿过墙壁。

为了评估关卡的难度,A 先生需要计算出从入口出发无法到达的方格总数。这个总数包括两部分:

  1. 原本就是墙壁的方格(值为
  2. 虽然是空地(值为 ),但被墙壁完全阻隔无法从入口到达的方格

例如,对于以下 的地图:

[[0,1,0,0],
 [0,0,0,0],
 [0,1,0,1],
 [0,0,1,0]]

由于位置 都是墙壁,导致位置 虽然是空地但无法从入口 到达。因此不可达的方格总数为 (原有的墙壁)(被阻隔的空地)

请帮助 A 先生编写一个程序,统计给定地图中不可达的方格总数。

输入格式

一行,包含一个 的二维数组,用方括号和逗号表示,数组中的元素为 。保证入口位置 的值为

输出格式

一行,输出一个整数,表示从入口出发无法到达的方格总数。

样例输入

[[0,1,1,0],[1,0,0,0],[0,1,0,1],[0,1,1,0]]
[[0,0,0,0],[1,0,0,1],[0,0,1,0],[0,0,0,1]]

样例输出

15
5
样例 解释说明
样例1 从入口 出发,只能到达 1 个空地方格(入口自己),其余 15 个方格都无法到达(包括 8 个墙壁和 7 个被阻隔的空地)
样例2 从入口出发可以到达 11 个空地方格,因此不可达的方格数为 (包括 4 个墙壁和 1 个被阻隔的空地位置

数据范围

  • 输入保证是 的方阵

  • 输入保证 位置的值为

题解

这道题本质上是一个连通性问题,需要找出从起点能够到达的所有空地,然后用总方格数减去可达方格数就是答案。

解题思路很直接:从入口 开始做一次广度优先搜索(BFS)或深度优先搜索(DFS),标记所有能够到达的空地方格。最后统计可达方格的数量,用 减去这个数量就得到不可达方格的总数。

具体实现步骤:

  1. 首先解析输入,提取出所有的 ,存入一维数组,通过开方可以得到 的值
  2. 使用 BFS 从位置 (对应 )开始搜索,用队列维护待访问的位置
  3. 对于当前位置,尝试向上下左右四个方向扩展,如果邻居位置是空地(值为 )且未访问过,就将其加入队列并标记为已访问
  4. BFS 结束后,统计访问过的方格数量 ,答案就是

为什么用 BFS 而不是单纯的遍历?因为题目要求判断连通性,不能到达的空地和墙壁一样算作不可达。BFS 能够准确地标记出所有与起点连通的空地。

时间复杂度分析:每个方格最多被访问一次,因此时间复杂度为 。对于 的数据范围,这个复杂度完全没有问题。

空间复杂度:需要存储地图数组和访问标记数组,空间复杂度也是

参考代码

  • Python
import sys
input = lambda: sys.stdin.readline().strip()
from collections import deque

# 读入一行并提取所有0和1
line = input()
grid = []
for ch in line:
    if ch == '0' or ch == '1':
        grid.append(int(ch))

# 计算网格大小
tot = len(grid)
n = int(tot ** 0.5)

# 如果起点是墙壁,直接返回全部方格数
if grid[0] == 1:
    print(tot)
else:
    # BFS 搜索可达区域
    vis = [False] * tot  # 访问标记数组
    q = deque([0])  # 队列,起点为0号位置
    vis[0] = True
    cnt = 0  # 可达方格计数
    
    while q:
        pos = q.popleft()
        cnt += 1
        r = pos // n  # 当前行
        c = pos % n   # 当前列
        
        # 尝试向四个方向扩展
        # 向上
        if r > 0:
            nxt = pos - n
            if grid[nxt] == 0 and not vis[nxt]:
                vis[nxt] = True
        

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

10-23 13:59
运营
最近这段时间,身边不少&nbsp;IT&nbsp;同行遭遇了&nbsp;“毕业”&nbsp;危机。看着他们为找工作焦虑奔波的模样,我不禁想起自己曾经失业时的经历。当时,正是依靠几个实用的网站,我才顺利度过空窗期,重新找到心仪的工作。今天,就把这&nbsp;4&nbsp;个能帮&nbsp;IT&nbsp;人快速回血的网站分享给大家,无论你是想找全职工作、接私活补贴收入,还是利用失业期学习新技能,总有一个能满足你的需求。一、牛客网:IT&nbsp;面试的&nbsp;“急救包”,全职求职快人一步对于想快速找到全职工作的&nbsp;IT&nbsp;人来说,牛客网绝对是不可错过的&nbsp;“利器”,堪称&nbsp;IT&nbsp;面试的&nbsp;“急救包”。这个网站收录了各大互联网公司的历年面试真题,内容覆盖全面且分类细致。从基础的&nbsp;Java&nbsp;语法、算法编程题,到复杂的架构设计、项目复盘案例,几乎涵盖了&nbsp;IT&nbsp;岗位面试的所有核心考点。更方便的是,网站支持在线敲代码刷题,每道题做错后都会有详细的解析,不仅能让你知道错在哪里,还能帮你理清解题思路,巩固相关知识点。我当年失业后,每天都会在牛客网花&nbsp;2&nbsp;小时刷题。尤其关注&nbsp;“面经板块”,这里有很多同行实时分享最新的面试流程和高频考点。比如某大厂近期面试时重点考察的微服务架构设计、分布式事务解决方案等内容,提前在面经里了解后,我就能针对性地准备应对思路,等到真正面试时,明显比没准备的人更从容,大大降低了紧张感。除此之外,牛客网的内推通道也十分实用。不少企业的&nbsp;HR&nbsp;会直接在平台上发布招聘需求,求职者可以跳过猎头环节,直接与&nbsp;HR&nbsp;沟通对接。这种方式不仅减少了中间流程,反馈速度也更快,能让你在求职竞争中抢占先机。二、IT&nbsp;找活网:IT&nbsp;人的&nbsp;“饭碗储备库”,私活变现两不误如果说牛客网是全职求职的好帮手,那&nbsp;IT&nbsp;找活网就是我失业期的&nbsp;“救命稻草”,它就像一个专属于&nbsp;IT&nbsp;人的&nbsp;“饭碗储备库”,靠它我当年接了&nbsp;3&nbsp;个私活,成功撑过了空窗期。和市面上那些综合类接单网站不同,IT&nbsp;找活网只聚焦&nbsp;IT&nbsp;领域。无论是软件开发、前端设计、移动端开发,还是当下热门的&nbsp;AI&nbsp;算法、数据分析、测试运维等需求,每天平台上都会更新大量真实的&nbsp;IT&nbsp;项目,没有杂七杂八的非&nbsp;IT&nbsp;需求干扰,能让你更精准地匹配到适合自己的机会。最让人省心的是,在这个平台上可以直接对接企业甲方,无需通过中介,也就不用被抽取佣金,自己的劳动所得能全部收入囊中。而且每个项目的预算、需求描述都写得明明白白,你还能查看甲方过往的合作评价,了解对方的信誉和合作模式,大大降低了踩坑的概率。我当时刚失业,凭借&nbsp;“Python&nbsp;开发”&nbsp;的技术栈在平台上匹配项目,仅仅&nbsp;3&nbsp;天就接到了一个小程序开发的私活。更值得一提的是,这个平台不只是能接私活,还支持技术经验变现。你可以把自己做项目时的踩坑笔记、技术总结写成文章,一旦有人查看并按需下载附件,你就能获得收益。我之前写的《Python&nbsp;爬虫反爬实战》,单月分成就相当可观。即便现在有了稳定工作,我也会每天登录刷一刷,既能接私活补贴收入,又能通过技术交流了解行业最新动态,保持对行业的敏感度。三、GitHub:技术能力的&nbsp;“加分项”,简历含金量&nbsp;UP&nbsp;UP失业期最忌讳的就是技术断档,而&nbsp;GitHub&nbsp;就是帮助&nbsp;IT&nbsp;人保持技术活跃度、提升简历含金量的绝佳平台,堪称技术能力的&nbsp;“加分项”。GitHub&nbsp;上有海量的开源项目,无论你是想练习新框架(比如近期热门的&nbsp;Vue3、SpringBoot3),还是想参与真实的开源协作、积累项目经验,都能在这里找到合适的机会。我当年失业时,为了让简历更有亮点,特意找了一个电商后台管理系统的开源项目参与其中,负责部分功能的代码开发。这段经历不仅让我熟练掌握了新的开发技术,还积累了实际的项目经验。当我把这段经历写进简历后,在面试中,面试官特意针对这个项目的细节进行提问,我能清晰地阐述开发思路和解决问题的方法,瞬间赢得了面试官的好感。现在很多公司招聘技术岗位时,都会关注求职者的&nbsp;GitHub&nbsp;主页。相比简历上空泛的&nbsp;“熟悉&nbsp;XX&nbsp;技术”,一个活跃的&nbsp;GitHub&nbsp;贡献记录,能更直观地展现你的技术能力和学习热情,让你在众多求职者中脱颖而出。四、慕课网:充电学习的&nbsp;“加油站”,补短板促提升如果想趁失业期弥补技术短板,学习新的技能方向,比如之前没接触过的&nbsp;AI&nbsp;开发、低代码开发等,慕课网就是一个优质的&nbsp;“加油站”。慕课网的&nbsp;IT&nbsp;课程体系非常完善,从入门级的基础课程到高阶的实战课程,覆盖了多个技术领域。而且课程大多结合实战项目,你可以跟着课程一步步完成项目开发,学完之后不仅能掌握相关技能,还能将项目经验写进简历,为求职加分。我当年失业后,就利用&nbsp;2&nbsp;周时间在慕课网上学习了&nbsp;Python&nbsp;数据分析课程,并跟着完成了一个用户行为分析的实战项目。后来面试一家数据服务公司时,这个项目正好与岗位需求对口,凭借项目中积累的经验,我顺利通过面试拿到了&nbsp;offer。更贴心的是,慕课网的很多课程都配备了专属学习群。在学习过程中遇到问题,你可以在群里向老师和同学请教,大家一起交流讨论,比自己一个人瞎琢磨效率高太多,能帮助你更快地掌握新知识。失业对于&nbsp;IT&nbsp;人来说,或许是职业道路上的一次短暂挫折,但只要选对工具、积极行动,就能快速调整状态,重返职场赛道。希望这&nbsp;4&nbsp;个网站能给正处于迷茫期的你带来帮助,也祝愿大家都能早日找到适合自己的发展方向,开启新的职业篇章!(注:文档部分内容可能由&nbsp;AI&nbsp;生成)
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务