游戏客户端——算法题

这些是腾讯光子游戏客户端面试中常见的算法与数学题。下面按题目分别给出思路和参考代码(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²)"。

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

相关推荐
raindayinrain1 小时前
c++新特性--实用新特性
c++
Soneswy1 小时前
C++基础篇——类与对象(中)
开发语言·c++
kiracrimson2 小时前
STL:List的使用和模拟实现
开发语言·c++·list
二十七日秋2 小时前
算法刷题笔记「Day 1|四道 OJ 入门题里的深坑」
c语言·汇编·数据结构·c++·笔记·python·算法
流年如夢2 小时前
继承与多态_继承篇
c++·继承·面向对象·c++进阶
沫璃染墨3 小时前
从零入门计算机网络系列(十):HTTP协议进阶——从资源路径解析到状态码与请求头详解
linux·运维·服务器·网络·c++·http
xiaoye-duck3 小时前
《C++ 工具库实战》高性能日志 spdlog:从基础使用到工程化封装
c++·第三方库
努力努力再努力wz3 小时前
【Lua入门系列】从 C++ 迭代器到 Lua 迭代器:一文深入理解 Lua 有状态以及无状态迭代器与泛型for、闭包、ipairs、pairs 和 next
开发语言·c++·lua
努力实干3 小时前
第二阶段 · 第 7 课:C++ 多线程与线程安全
开发语言·c++·安全
小菜要扣篮5 小时前
Ubuntu 下使用 vscode 打开 C++ 项目后,无法通过 F12 定位到定义问题解决
c++·vscode·ubuntu