对于左神课上讲到的算法题,自己从头到尾基本敲了一遍,因为是先回忆了几道题后,有重新打开网课看了一下题目,因此顺序可能和讲课顺序不太一样,不过应该基本都实现了。
这里先给两个链表结点数据结构,一个带有随机指针,一个不带。
class ListNode {
public:
ListNode();
ListNode(int val);
int val;
ListNode* next;
};
//带随机指针的链表
class ListNode1 {
public:
ListNode1();
ListNode1(int val);
int val;
ListNode1* next;
ListNode1* random;
};
1.判断是否有环
bool test01(ListNode* node) {
ListNode* slow = node;
ListNode* fast = node;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (fast == slow) {
return true;
}
}
return false;
}
2.判断两个无环链表的第一个相交结点
ListNode* test02(ListNode* node1, ListNode* node2) {
if (node1 == nullptr || node2 == nullptr) {
return nullptr;
}
ListNode* head1 = node1;
ListNode* head2 = node2;
while (head1 != nullptr && head2 != nullptr) {
if (head1 == head2) return head1;
head1 = head1->next == nullptr ? node2 : head1->next;
head2 = head2->next == nullptr ? node1 : head2->next;
}
return nullptr;
}
3.深拷贝带随机指针的链表
ListNode1* test03(ListNode1* head) {
/*
* //哈希表
if (node == nullptr) {
return nullptr;
}
ListNode1* head = node;
ListNode1* newHead = new ListNode1();
ListNode1* tmp = newHead;
std::unordered_map<ListNode1*, ListNode1*> map;
while (head != nullptr) {
ListNode1* newNode = new ListNode1(head->val);
map[head] = newNode;
tmp->next = newNode;
tmp = tmp->next;
head = head->next;
}
head = node;
tmp = newHead->next;
while (head != nullptr) {
tmp->random = map[head->random];
tmp = tmp->next;
head = head->next;
}
return newHead->next;
*/
//指针
if (head == nullptr) return nullptr;
ListNode1* node1 = head;
ListNode1* newHead = new ListNode1(0);
while (node1 != nullptr) {
ListNode1* newNode = new ListNode1(node1->val);
ListNode1* next = node1->next;
node1->next = newNode;
newNode->next = next;
node1 = next;
}
node1 = head;
while (node1 != nullptr) {
if (node1->random != nullptr)
node1->next->random = node1->random->next;
node1 = node1->next->next;
}
node1 = head;
newHead->next = head->next;
ListNode1* node2 = newHead->next;
while (node1 != nullptr) {
node1->next = node2->next;
node1 = node1->next;
if (node2->next != nullptr) {
node2->next = node2->next->next;
node2 = node2->next;
}
}
return newHead->next;
}
4.翻转链表
ListNode* test04(ListNode* node) {
ListNode* cur = node;
ListNode* pre = nullptr;
while (cur != nullptr) {
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
5.输入链表头结点,奇数长度返回中点,偶数长度返回上中点
ListNode* test05(ListNode* head) {
if (head == nullptr || head->next == nullptr || head->next->next == nullptr) {
return head;
}
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
6.输入链表头节点 奇数长度返回中点 偶数长度返回下中点
ListNode* test06(ListNode* head) {
if (head == nullptr || head->next == nullptr) return head;
if (head->next->next == nullptr) return head->next;
ListNode* slow = head->next;
ListNode* fast = head->next;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
7.输入链表头节点 奇数长度返回中点前一个 偶数长度返回上中点前一个
ListNode* test07(ListNode* head) {
if (head == nullptr || head->next == nullptr) return nullptr;
if (head->next->next == nullptr) return head;
ListNode* slow = head;
ListNode* fast = head->next->next;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
8.输入链表头节点 奇数长度返回中点前一个 偶数长度返回上中点前一个
ListNode* test08(ListNode* head) {
if (head == nullptr || head->next == nullptr) return nullptr;
if (head->next->next == nullptr) return head;
ListNode* slow = head;
ListNode* fast = head->next;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
9.回文链表
bool test09(ListNode* head) {
if (head == nullptr) {
return false;
}
if (head->next == nullptr) {
return true;
}
ListNode* slow = head;
ListNode* fast = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* head2 = slow->next;
slow->next = nullptr;
//使用之前写好的翻转链表
ListNode* head2 = test04(head2);
fast = head2;
slow = head;
while (head2->next != nullptr) {
if (slow->val != head2->val) return false;
slow = slow->next;
fast = fast->next;
}
return true;
}
10.把单向链表按某值划分为左边小,中间相等,右边大的形式
ListNode* test10(ListNode* head, int val) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* sh = nullptr;
ListNode* se = nullptr;
ListNode* eh = nullptr;
ListNode* ee = nullptr;
ListNode* bh = nullptr;
ListNode* be = nullptr;
ListNode* node = head;
while (node != nullptr) {
ListNode* next = node->next;
if (node->val < val) {
if (sh == nullptr) {
sh = head;
se = head;
}
else {
se->next = head;
se = head;
}
}
else if (node->val == val) {
if (eh == nullptr) {
eh = head;
ee = head;
}
else {
ee->next = head;
ee = head;
}
}
else {
if (bh == nullptr) {
bh = head;
be = head;
}
else {
be->next = head;
be = head;
}
}
node = next;
}
se->next = eh;
ee->next = bh;
be->next = nullptr;
return sh;
}