游戏客户端——算法题

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


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

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

  1. 定义两个指针 fastslow,都指向头节点。
  2. fast 先向前走 k 步。
  3. 然后 fastslow 同时向前走,直到 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 * 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²)"。

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

相关推荐
Xia__Quan1 小时前
centos 共享文件夹
c++
hi_ro_a2 小时前
基于正倒排索引的boost搜索引擎
linux·c++·搜索引擎·项目
神仙别闹2 小时前
基于 C++ MFC 实现的个人通讯录管理系统
c++
GG-_-Bond2 小时前
9.1kv存储持久化模拟面试
linux·c语言·数据结构·c++
郝学胜-神的一滴3 小时前
C++20模板元编程 04:变量模板 别名模板与模板Lambda实战
服务器·开发语言·数据结构·c++·程序人生
qq_344920563 小时前
Qt事件过滤器
开发语言·c++·qt
码匠许师傅4 小时前
【C++三方组件】fmt:C++字符串格式化的前世今生
c++
anew___4 小时前
舵机——让 Arduino 动起来
c++·stm32·单片机·嵌入式硬件·c
qq_344920564 小时前
Qt 鼠标双击QLabel全屏显示图像
c++·qt