前言
链表常见面试题
一、回文链表
题目:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution
{
public:
bool isPalindrome(ListNode* head) {
if(head==nullptr)
{
return false;
}
if(head->next==nullptr)
{
return true;
}
ListNode* n1 = head;
ListNode* n2 = head;
while(n2->next!=nullptr && n2->next->next!=nullptr)//通过快慢指针找到中间节点
{
n1 = n1->next;
n2 = n2->next->next;
}
ListNode* mid = n1;
n2 = n1->next;
n1->next = nullptr;//将中间指针next指针置空
ListNode* n3 = nullptr;
while(n2!=NULL)//从中间节点的下一个节点开始反转
{
n3 = n2->next;
n2->next = n1;
n1 = n2;
n2 = n3;
}
n3 = n1;
n1 = head;
n2 = n3;
bool s = true;
while(n1!=nullptr && n3!=nullptr)//从两边到中间进行比对
{
if(n1->val!=n3->val)
{
s = false;
break;
}
n1 = n1->next;
n3 = n3->next;
}
n1 = nullptr;
n3 = n2->next;
while(n2!=NULL)//将有部分进行反转回来
{
n3 = n2->next;
n2->next = n1;
n1 = n2;
n2 = n3;
}
return s;
}
};
二、分隔链表
题目:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* ST = nullptr;//记录小于x第一个节点
ListNode* SH = nullptr;//记录小于x的最后一个节点
ListNode* MT = nullptr;//记录大于x的第一个节点
ListNode* MH = nullptr;//记录大于x的最后一个节点
ListNode* cur = head;
while (cur != nullptr)
{
ListNode* next = cur->next;//记录下一个节点
cur->next = NULL;//将其置空
if (cur->val < x)
{
if (SH == NULL)
{
ST = cur;
SH = cur;
}
else
{
ST->next = cur;
ST = cur;
}
}
else
{
if (MH == NULL)
{
MT = cur;
MH = cur;
}
else
{
MT->next = cur;
MT = cur;
}
}
cur = next;
}
if (SH == NULL)
{
return MH;
}
ST->next = MH;
return SH;
}
};
三、复制带随机指针的链表
题目:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr)
{
return nullptr;
}
Node* cur = head;
while(cur!=nullptr)
{
Node* next = cur->next;//记录下一个节点
Node* newnode = new Node(cur->val);//克隆该节点
cur->next = newnode;//当前节点链接克隆节点
newnode->next = next;//克隆节点链接原先节点的下一个节点
cur = next;
}
cur = head;
Node* newhead = head->next;
while(cur!=nullptr)//
{
Node* next = cur->next->next;
Node* clone = cur->next;//通过原节点的random所连节点的下一个找到克隆节点对应的random
clone->random = cur->random==nullptr?nullptr:cur->random->next;
cur = next;
}
cur = head;
while(cur!=nullptr)//将原节点和克隆节点分开
{
Node* next = cur->next->next;
Node* clone = cur->next;
clone->next = clone->next!=nullptr?clone->next->next:nullptr;
cur->next = next;
cur = next;
}
return newhead;
}
};
四、相交链表
题目:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
int n1 = 0;//记录A链表的长度
int n2 = 0;//记录B链表的长度
ListNode* curA = headA;
ListNode* curB = headB;
while (curA != nullptr)
{
curA = curA->next;
n1++;
}
while (curB != nullptr)
{
curB = curB->next;
n2++;
}
if (curB != curA)//A链表的节点不等于B最后节点的说明必定不相交
{
return nullptr;
}
ListNode* ML = n1 >= n2 ? headA : headB;//ML指代较长链表
ListNode* SL = n1 < n2 ? headA : headB;//SL指代较短链表
int s = fabs(n1 - n2);
for (int i = 0; i < s; i++)//让较长链表先走s步(长度差)
{
ML = ML->next;
}
while (ML != SL)
{
ML = ML->next;
SL = SL->next;
}
return ML;
}
};
总结
以上就是面试常见链表题,希望对大家有所帮助!