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

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

虾皮-2026.03.08

这套题整体很典型:第一题是排序加双指针的标准计数题,第二题考的是字符串中心扩展,第三题则回到最基础的二叉树层序遍历。难度分层比较清晰,前两题更看重是否能迅速抓住经典模型,第三题偏热身。

题目一:三角形组合数量

这题表面是在数三元组,真正关键是把“三角形条件”转成排序后的单调性。固定最长边以后,双指针可以一次性统计整段合法区间,不需要一个个三元组去试。

难度:中等

题目二:找出最长回文字串

题面已经把范围收窄到“只考虑奇数长度回文”,所以直接枚举中心往两边扩展就够了。容易忽略的是同长度时要返回第一个,这意味着更新答案时只能在“更长”时替换。

难度:中等

题目三:二叉树遍历

这题本质就是层序遍历,难点主要在输入还原:要先把带 # 的层序序列建成树,再做标准 BFS。实现上只要把“当前层节点数”先记下来,按层输出就很自然了。

难度:简单

01. 三角展架方案统计

问题描述

小兰正在布置一个展厅。仓库里有 根轻型支架,每根支架都有一个长度值。现在她想从中选出 3 根支架,拼成一个稳定的三角展架。

只有当任意两根支架的长度和都大于第三根时,这 3 根支架才能组成三角形。请统计一共有多少种不同的选法。

输入格式

一行,输入一个整数 和一个长度数组,格式如 4,[1,1,1,1]

输出格式

输出一个整数,表示可以组成三角形的三元组数量。

样例输入

4,[1,1,1,1]

样例输出

4

数据范围

样例 解释说明
样例1 4 根支架长度都为 1,任取 3 根都满足三角形条件,所以答案是

题解

这道题最朴素的想法是枚举所有三元组,但这样需要 ,当 达到 时肯定过不去。

更合适的做法是先排序。排完序以后,如果固定某个位置 作为最长边,那么只要另外两条边满足

就能组成三角形。因为数组有序,所以一旦某个 ij 满足条件,那么区间 i..j-1 中的所有位置都和 j 一起满足条件,可以一次性把这些方案全部加进答案里。

具体步骤如下:

  1. 将数组升序排序。
  2. 从右到左枚举最长边位置
  3. 设两个指针 i=0j=k-1
  4. 如果 ,说明 i..j-1 这些左端点都合法,此时答案加上 j-i,再把 j 左移。
  5. 否则说明当前最短边太短,需要把 i 右移。

每个 的双指针扫描都是线性的,所以总复杂度是 ,能够满足题目要求。

参考代码

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

def solve():
    line = input()
    # 提取整行中的所有整数,兼容 `n,[...]` 这种输入格式。
    nums = list(map(int, re.findall(r'-?\d+', line)))
    if not nums:
        print(0)
        return

    # 优先按题图中的格式处理:第一个数是 n,后面是数组元素。
    if len(nums) >= 2 and nums[0] == len(nums) - 1:
        arr = nums[1:]
    else:
        arr = nums

    # 排序后才能使用双指针批量计数。
    arr.sort()
    n = len(arr)
    ans = 0

    # 枚举最长边的位置。
    for k in range(n - 1, 1, -1):
        i, j = 0, k - 1
        while i < j:
            # 当前最短边和次长边已经能超过最长边。
            if arr[i] + arr[j] > arr[k]:
                # 那么 i..j-1 都能与 j 组成合法三角形。
                ans += j - i
                j -= 1
            else:
                # 最短边太短,需要增大它。
                i += 1

    print(ans)

if __name__ == "__main__":
    solve()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

vector<int> parse_nums(const string& line) {
    vector<int> nums;
    int i = 0, n = (int)line.size();
    while (i < n) {
        if (isdigit(line[i]) || line[i] == '-') {
            int j = i;
            if (line[i] == '-') {
                i++;
            }
            while (i < n && isdigit(line[i])) {
                i++;
            }
            nums.push_back(stoi(line.substr(j, i - j)));
        } else {
            i++;
        }
    }
    return nums;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string line;
    getline(cin, line);

    // 解析输入中的所有整数。
    vector<int> nums = parse_nums(line);
    if (nums.empty()) {
        cout << 0 << '\n';
        return 0;
    }

    vector<int> arr;
    if ((int)nums.size() >= 2 && nums[0] == (int)nums.size() - 1) {
        // 题图中的格式:第一个数是 n,后面是数组内容。
        arr.assign(nums.begin() + 1, nums.end());
    } else {
        arr = nums;
    }

    sort(arr.begin(), arr.end());
    long long ans = 0;
    int n = (int)arr.size();

    // 从右到左枚举最长边。
    for (int k = n - 1; k >= 2; --k) {
        int i = 0, j = k - 1;
        while (i < j) {
            if (arr[i] + arr[j] > arr[k]) {
                // 固定 j 时,i..j-1 都合法。
                ans += j - i;
                --j;
            } else {
                ++i;
            }
        }
    }

    cout << ans << '\n';
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

public class Main {
    private static List<Integer> parseNums(String line) {
        List<Integer> nums = new ArrayList<>();
        int i = 0, n = line.length();
        while (i < n) {
            char ch = line.charAt(i);
            if (Character.isDigit(ch) || ch == '-') {
                int j = i;
                if (ch == '-') {
                    i++;
                }
                while (i < n && Character.isDigit(line.charAt(i))) {
                    i++;
                }
                nums.add(Integer.parseInt(line.substring(j, i)));
            } else {
                i++;
            }
        }
        return nums;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();

        List<Integer> nums = parseNums(line);
        if (nums.isEmpty()) {
            System.out.println(0);
            return;
        }

        List<Integer> arr = new ArrayList<>();
        if (nums.size() >= 2 && nums.get(0) == nums.size() - 1) {
            // 按 `n,[...]` 的输入方式取出真实数组。
            for (int i = 1; i < nums.size(); i++) {
                arr.add(nums.get(i));
            }
        } else {
            arr.addAll(nums);
        }

        Collections.sort(arr);
        long ans = 0;
        int n = arr.size();

        // 枚举最长边。
        for (int k = n - 1; k >= 2; k--) {
            int i = 0, j = k - 1;
            while (i < j) {
                if (arr.get(i) + arr.get(j) > arr.get(k)) {
                    // 对当前 j,区间 i..j-1 都能组成三角形。
                    ans += j - i;
                    j--;
                } else {
                    i++;
                }
            }
        }

        System.out.println(ans);
    }
}

02. 灯带最美对称段

问题描述

小兰正在设计一条互动灯带。灯带会显示一串字符,她想从中截出一段“最对称”的内容,作为开场动画的核心片段。

如果一个字符串正着读和反着读完全一样,就把它看作回文字串。现在给定一个字符串 ,请找出其中最长的奇数长度回文字串;如果有多个长度相同的答案,返回最先出现的那个。

输入格式

一行,一个字符串,格式如 "babad"

输出格式

输出满足要求的最长奇数长度回文字串,格式与样例一致。

样例输入

"babad"

样例输出

"bab"

数据范围

  • 题图没有展示明确范围。为了便于本地 OJ 落地,这里补充为:

  • 字符串仅包含英文字母。

样例 解释说明
样例1 "bab""aba" 都是长度为 3 的奇数回文,但题目要求有多个答案时返回第一个,所以输出 "bab"

题解

因为题目明确要求“回文字串的长度是奇数”,所以没有必要去处理偶数长度中心,只需要枚举每个字符作为中心即可。

设当前中心在位置 。从这个位置开始,令两个指针同时向左右扩展:

  • 左指针从 往左走。
  • 右指针从 往右走。
  • 只要两边字符相同,就说明当前区间仍然是回文。

这样就能枚举出所有以 为中心的奇数长度回文。对每个中心都做一次扩展,记录最长答案即可。

有一个小细节:如果遇到多个相同长度的答案,题目要求返回第一个。处理起来很简单——只有在“更长”时才更新答案,长度相同就保持原结果不变。因为枚举中心是从左到右进行的,所以最先记录下来的自然就是更靠前的答案。

时间复杂度是 ,因为每个中心最坏都会向两边扩展到整串长度。空间复杂度是

参考代码

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

def strip_quote(s):
    # 兼容样例中的双引号写法,也兼容直接输入原字符串。
    if len(s) >= 2 and s[0] == s[-1] and s[0] in "\"'":
        return s[1:-1]
    return s

def solve():
    s = strip_quote(input())
    n = len(s)
    if n == 0:
        print('""')
        return

    # 初始答案至少包含一个字符。
    best_l = 0
    best_len = 1

    # 每个位置都作为奇数长度回文的中心。
    for c in range(n):
        l = r = c
        while l >= 0 and r < n and s[l] == s[r]:
            cur_len = r - l + 1
            # 只有更长时才更新,保证相同长度保留第一个。
            if cur_len > best_len:
                best_len = cur_len
                best_l = l
            l -= 1
            r += 1

    ans = s[best_l:best_l + best_len]
    print('"' + ans + '"')

if __name__ == "__main__":
    solve()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

string strip_quote(string s) {
    if (s.size() >= 2 && s.front() == s.back() &&
        (s.front() == '"' || s.front() == '\'')) {
        return s.substr(1, s.size() 

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

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

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

全部评论

相关推荐

牛客44320985...:你的当务之急是把这个糖的要死的沟槽ide主题改了
点赞 评论 收藏
分享
评论
1
4
分享

创作者周榜

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