面试中常见的链表题目汇总
重点解决 LeetCode 中 List 为 Top Interview Questions 且 Tag 为 Linked List 的题目。
0 如何写测试代码
以下是以 LeetCode 2 为例的,在 LeetCode Playground 完成的 C++ 实现及测试代码:
https://leetcode.com/playground/WmFSQPkU
其中,测试代码主要包含以下几个部分:
定义单向链表节点:
struct MyListNode {
int val;
MyListNode* next;
MyListNode() : val(0), next(nullptr) {}
MyListNode(int val) : val(val), next(nullptr) {}
MyListNode(int val, MyListNode* next) : val(val), next (next) {}
};打印链表:
void print_list(MyListNode* node) {
std::ostringstream oss;
while (node) {
oss << node->val << "->";
node = node->next;
}
oss << "NULL" << std::endl;
std::cout << oss.str();
}判断两个链表是否相等:
bool is_equal_list(MyListNode* l1, MyListNode* l2) {
if (!l1 && !l2) return true;
if (!l1 || !l2 || l1->val != l2->val) return false;
return is_equal_list(l1->next, l2->next);
}将数组转换为链表:
MyListNode* vec2list(const std::vector<int>& vec, int beg, int end) {
int n = vec.size();
if (end >= n || beg > end) return nullptr;
MyListNode* node = new MyListNode(
vec[beg], vec2list(vec, beg+1, end)
);
return node;
}这样,我们就可以通过给定数组来测试链表了:
std::vector<vector<int>> args_1 = {
{},
{},
{1, 2, 3, 4},
{8, 9, 9, 8},
};
std::vector<vector<int>> args_2 = {
{},
{1},
{1, 2, 3, 4},
{1, 2, 3, 4},
};
std::vector<vector<int>> rets = {
{},
{1},
{2, 4, 6, 8},
{9, 1, 3, 3, 1},
};在主函数中测试:
int main() {
int n = rets.size();
for (int i = 0; i < n; ++i) {
MyListNode* arg_1 = vec2list(args_1[i], 0, args_1[i].size()-1);
// print_list(arg_1);
MyListNode* arg_2 = vec2list(args_2[i], 0, args_2[i].size()-1);
// print_list(arg_2);
MyListNode* ret = vec2list(rets[i], 0, rets[i].size()-1);
// print_list(ret);
assert(
is_equal_list(add_two_numbers(arg_1, arg_2), ret)
);
}
}
1 反转链表
LeetCode 206. Reverse Linked List
题意
给定一个链表,将其反转。
思路
以相邻三个元素 pre
、cur
和 nxt
的处理过程为一个周期,在此周期内:
首先将
cur->next
记录到nxt
中然后将
cur->next
置为pre
,完成cur
位置上的反转最后将
pre
移动至cur
的位置,将cur
移动至nxt
的位置
可以参考这个动图:How to Reverse Linked List
C++ 实现
/** |
2 排序链表
题意
给定一个链表,将其升序排序。
思路
使用归并排序或快速排序,基本思想与数组的排序算法保持一致,只是由于链表的特殊结构,在实现上要做特殊处理。
C++ 实现
归并排序:
/** |
快速排序:
/** |