题目: 对于一个链表,请设计一个时间复杂度为 O(N), 额为空间复杂度为 O(1), 判断其时候为回文结构。
解题思路:
![](https://i-blog.csdnimg.cn/direct/2b13baca7b5d47b7b17a94d5e174886a.png)
cpp
//反转链表函数
typedef struct ListNode ListNode;
ListNode* reverseList(ListNode* head)
{
//原链表为空节点
if (head == NLUU)
{
return head;
}
ListNode* n1, *n2, *n3;
n1 = NULL, n2 = head, n3 = n2->next;
while (n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3)
n3 = n3->next;
}
return n1;
}
//找中间节点函数
ListNode* middleNode(ListNode* head)
{
//创建快慢指针
ListNode* slow = head;
ListNode* fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
//判断是否回文
bool chkPalindrome(ListNode* A)
{
ListNode* mid = middleNode(A);
ListNode* rmid = reverseList(mid);
while (rmid && A)
{
if (rmid->val != A->val)
{
return false;
}
rmid = rmid->next;
A = A->next;
}
return true;
}
题目: 给定两个单链表的头节点 headA 和 headB, 请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 NULL
相交链表如图所示:
![](https://i-blog.csdnimg.cn/direct/2e0af6e0ef5e40cfa75491996fbfd4eb.png)
判断是否相交就是去判断两链表的尾指针地址是否相等,若相交,则尾节点一定相同;不相交就一定不同。
如何找到相交交界点呢?
思路一:
将A链表的每一个节点的地址与B链表比较,有相等的那就是相交节点 (该时间复杂度为 O(M * N) 或 O(N^2) )
思路二:
分别来遍历两链表,算出两链表的长度, 两个长度的差值便是多出来的节点,让长的链表先走完多的,再同时一起走,判断是否有相同的节点。(此时的时间复杂度是 O(N))
cpp
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
struct ListNode* curA = headA;
struct ListNode* curB = headB;
int lenA = 1;
int lenB = 1;
//先判断是否相交
while (curA->next)
{
curA = curA->next;
++lenA;
}
while (curB->next)
{
curB = curB->next;
++lenB;
}
if (curA != curB)
{
return NULL;
}
//找相交节点
//长的先走,再同时走
int gap = abs(lenA - lenB);
struct ListNode* longList = headA, *shortList = headB;
if (lenB > lenA)
{
longList = headB;
shortList = headA;
}
while (gap--)
{
longList = longList->next;
}
while (longList != shortList)
{
longList = longList->next;
shortList = shortList->next;
}
return longList;
}
再附赠一题: 返回链表倒数第 k 个节点
题目: 实现一种算法,找出单链表中倒数第 k 个节点,返回该节点的值。(要求: 空间复杂度为 O(1), 只能遍历链表一遍)
如果没有限制条件,我们既可以遍历两次链表,第一次得到一共有多少个节点,第二次遍历 n - k 次找到倒数第 k 个节点;也可以用数组将所有值保存起来,并用下标直接找到倒数第 k 个值。
有了限制,我们便有了更巧妙地方法 ------ 快慢指针法
![](https://i-blog.csdnimg.cn/direct/4c952c57c41b4d68ba3f6cdc448044e9.png)
cpp
int kthToLast(struct ListNode* head, int k)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
//fast 先走k步
while (k--)
{
fast = fast->next;
}
//同时走
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow->val;
}