目录
剑指 Offer 22. 链表中倒数第k个节点
定义快慢指针,先让fast走k步,走完k步跟slow同步走,当fast走NULL时,slow即为要找的节点,返回slow即可。
struct ListNode* getKthFromEnd(struct ListNode* head, int k)
{
struct ListNode* fast, * slow;
slow = fast = head;
//fast先走k步
while (k--)
{
//fast还没走出k步,链表没有k步长
if (fast == NULL)
return NULL;
fast = fast->next;
}
//同步走
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
21. 合并两个有序链表
不带哨兵位
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL)
return list2;
if (list2 == NULL)
return list1;
struct ListNode* head, * tail;
head = tail = NULL;
//其中有一个走到尾时结束
while (list1 && list2)
{
if (list1->val < list2->val)
{
if (tail == NULL)
head = tail = list1;
else
{
tail->next = list1;
tail = tail->next;
}
list1 = list1->next;
}
else
{
if (tail == NULL)
head = tail = list2;
else
{
tail->next = list2;
tail = tail->next;
}
list2 = list2->next;
}
}
if (list1)
tail->next = list1;
if (list2)
tail->next = list2;
return head;
}
带哨兵位
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode* head, * tail;
//哨兵
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
tail->next = NULL;
//其中有一个走到尾时结束
while (list1 && list2)
{
if (list1->val < list2->val)
{
//无需判断是否为头节点
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
else
{
//无需判断是否为头节点
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
}
if (list1)
tail->next = list1;
if (list2)
tail->next = list2;
struct ListNode* list = head->next;
free(head);
return list;
}
面试题 02.04. 分割链表![](https://img-blog.csdnimg.cn/e777c46df2024e5fb49a4989ab1970ba.png)
struct ListNode* partition(struct ListNode* head, int x)
{
//创建哨兵位
struct ListNode* greaterhead, * greatertail, * lesshead, * lesstail;
greaterhead = greatertail = (struct ListNode*)malloc(sizeof(struct ListNode));
lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));
greaterhead->next = NULL;
lesshead->next = NULL;
//定义跟随指针
struct ListNode* cur = head;
while (cur)
{
//将大小与x的值进行分组
if (cur->val < x)
{
lesstail->next = cur;
lesstail = lesstail->next;
}
else
{
greatertail->next = cur;
greatertail = greatertail->next;
}
cur = cur->next;
}
//最后将两组进行链接
lesstail->next = greaterhead->next;
//防止带环
greatertail->next = NULL;
//释放哨兵位
struct ListNode* phead = lesshead->next;
free(greaterhead);
free(lesshead);
//返回新链表头节点
return phead;
}
LCR 027. 回文链表![](https://img-blog.csdnimg.cn/8a711de2fd874665ab631078047b50c4.png)
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* slow, * fast;
slow = fast = head;
//fast:检验奇数,fast->next:检验偶数
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
struct ListNode* reverseList(struct ListNode* head)
{
//防止链表为空
if (head == NULL)
{
return NULL;
}
struct ListNode* n1, * n2, * n3;
n1 = NULL;
n2 = head;
n3 = n2->next;
while (n2)
{
//倒指向
n2->next = n1;
//迭代
n1 = n2;
n2 = n3;
//防止n3越界访问
if (n3)
n3 = n3->next;
}
//最后一步时,n1=n2处于反转后首元素位置,故直接return n1
return n1;
}
bool isPalindrome(struct ListNode* head)
{
//找到中间节点
struct ListNode* mid = middleNode(head);
//将中间节点后的链元素逆置
struct ListNode* rhead = reverseList(mid);
//用两个指针检查链mid前元素与mid后逆置元素进行一一比较
while (head && rhead)
{
if (head->val != rhead->val)
{
return false;
}
else
{
head = head->next;
rhead = rhead->next;
}
}
return true;
}
LCR 023. 相交链表![](https://img-blog.csdnimg.cn/edc0a000647142bb88088505b540d2f5.jpeg)
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
//以防过于复杂,后遍历A,B的长度,长度相减,相差的值即为其中一长链元素要跳过的个数
//使时间复杂度变为O(n)
if (headA == NULL || headB == NULL)
return NULL;
struct ListNode* curA = headA, * curB = headB;
int lenA = 1, lenB = 1;
//计算各自的长度
while (curA->next)
{
curA = curA->next;
lenA++;
}
while (curB->next)
{
curB = curB->next;
lenB++;
}
//走到末尾是若两节点值不相同则不相交
if (curA != curB)
return NULL;
//求第一个交点
struct ListNode* shortList = headA, * longList = headB;
//分出长短
if (lenA > lenB)
{
shortList = headB;
longList = headA;
}
//abs库函数: 求绝对值
int gap = abs(lenA - lenB);
//长的先走gap步
while (gap--)
{
longList = longList->next;
}
//找到相交点
while (shortList != longList)
{
shortList = shortList->next;
longList = longList->next;
}
//返回相交点位置
return shortList;
}
141. 环形链表
bool hasCycle(struct ListNode* head)
{
//定义快慢指针
struct ListNode* slow, * fast;
slow = fast = head;
//考虑单复数情况
while (fast && fast->next)
{
//slow每次走一步,fast每次走两步
slow = slow->next;
fast = fast->next->next;
//slow与fast相遇,表示为闭环
if (slow == fast)
return true;
}
//fast走空时没追上slow表示不是闭环
return false;
}
创作不易如果有帮助的话就请留下一个免费的赞吧!(❁´◡`❁)