游戏客户端——算法题

这些是腾讯光子游戏客户端面试中常见的算法与数学题。下面按题目分别给出思路和参考代码(C++)。


1. 如何获得链表中倒数第 k 个数

思路:快慢指针(双指针)

  1. 定义两个指针 fast 和 slow,都指向头节点。
  2. fast 先向前走 k 步。
  3. 然后 fast 和 slow 同时向前走,直到 fast 走到链表末尾(nullptr)。
  4. 此时 slow 指向的就是倒数第 k 个节点。

注意边界:

  • 链表为空;
  • k <= 0;
  • k 大于链表长度。

代码示例:

cpp 复制代码
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode* findKthFromEnd(ListNode* head, int k) {
    if (!head || k <= 0) return nullptr;

    ListNode* fast = head;
    ListNode* slow = head;

    // fast 先走 k 步
    for (int i = 0; i < k; ++i) {
        if (!fast) return nullptr; // k 大于链表长度
        fast = fast->next;
    }

    // 同时走
    while (fast) {
        fast = fast->next;
        slow = slow->next;
    }

    return slow;
}

复杂度:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

2. 圆内均匀随机点

圆心 (0,0),半径 R,要求给出圆内的一个随机点。

错误做法

直接随机 x ∈ [-R, R],y ∈ [-R, R],然后判断 x² + y² <= R²。

这样虽然可以,但拒绝采样效率低(约 78.5% 接受率),而且如果直接取 r = rand(0, R)、θ = rand(0, 2π),点会向圆心聚集,不是均匀分布。

正确做法:极坐标 + 面积均匀

圆内均匀分布要求概率密度与面积成正比。

令:

  • θ = 2π * rand01()
  • r = R * sqrt(rand01())

因为面积正比于 r²,所以 r 的累积分布函数是 (r/R)²,反变换得到 r = R * sqrt(u)。

代码示例:

cpp 复制代码
#include <cmath>
#include <cstdlib>

struct Point { double x, y; };

double rand01() {
    return rand() / (double)RAND_MAX;
}

Point randomPointInCircle(double R) {
    double theta = 2.0 * M_PI * rand01();
    double r = R * std::sqrt(rand01());
    return { r * std::cos(theta), r * std::sin(theta) };
}

验证:

  • 面积均匀:r 的分布满足 P(r < r0) = (r0/R)²;
  • 角度均匀:θ 在 [0, 2π) 均匀分布。

3. 快速排序的时间复杂度,最坏情况是多少

  • 平均时间复杂度: O(n log n)
  • 最好时间复杂度: O(n log n)
  • 最坏时间复杂度: O(n²)

最坏情况出现在:

每次选择的基准值(pivot)都是当前区间的最小值或最大值,导致划分极度不平衡。

例如:

  • 数组已经有序;
  • 每次取第一个或最后一个元素作为 pivot。

此时递归深度为 n,每层划分代价为 O(n),总代价 O(n²)。

优化方法:

  • 随机选择 pivot;
  • 三数取中;
  • 小数组用插入排序;
  • 三路划分处理大量重复元素。

空间复杂度:

  • 平均:O(log n)(递归栈)
  • 最坏:O(n)

面试加分点

  1. 链表题:可以提"如果链表长度未知,快慢指针只需遍历一次;如果允许修改链表,也可以先反转再找,但会改变结构"。
  2. 随机点题 :面试官很可能考察"为什么不能直接随机 r",一定要解释 sqrt 的原因。
  3. 快排题 :可以顺带提"C++ std::sort 通常是内省排序(introsort),结合快排、堆排和插入排序,避免最坏 O(n²)"。

这些问题在游戏客户端面试中很常见,重点考察基础数据结构和概率分布的理解。

相关推荐
fpcc7 小时前
c++编程实践—堆和栈越界调试
c++
weiabc8 小时前
MSYS2 UCRT64 + g++ C++ 中文输出乱码 完整全过程
c++
灯澜忆梦9 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
aqiu11111111 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
chenbingjie_c11 小时前
C++ STL 适配器:stack & queue,从 vector/list 到 deque 深度解析
数据结构·c++
hetao173383715 小时前
2026-10-08 hetao1733837 的刷题记录
c++·算法
Frank_refuel15 小时前
【C++】智能指针
开发语言·c++
一只旭宝16 小时前
数据结构与算法复习手册:从写过,到讲清楚
开发语言·数据结构·c++·算法
十五年专注C++开发16 小时前
std::filesystem::exists 在有的win10系统抛异常原因分析
c++·文件系统·filesystem
hetao173383717 小时前
2026-10-07 hetao1733837 的刷题记录
c++·算法