给定两个单链表,判断它们是否相交,若相交则返回相交的节点。(注意:判断依据是节点地址是否相同,而非节点值,因为节点值可能存在重复。)
gap
。gap
步。思路2的时间复杂度更低,所以我们选择思路2
具体代码如下
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
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++;
}
int gap=abs(lenA-lenB);
//假设法 先假设A长
struct ListNode* longList=headA;
struct ListNode* shortList=headB;
if(lenA<lenB)
{
longList=headB;
shortList=headA;
}
while(gap--)
{
longList=longList->next;
}
while(longList)
{
if(longList==shortList)
return longList;
longList=longList->next;
shortList=shortList->next;
}
return NULL;
}
判断一个单链表是否为回文结构。即正着读和反着读都一样
回文链表判断的关键在于对称性验证。我们可以通过以下步骤实现:
class PalindromeList {
public:
//寻找中间节点
struct ListNode* middleNode(struct ListNode* head) {
// 初始化快慢指针
struct ListNode* slow = head;
struct ListNode* fast = head;
// 移动指针直到fast到达链表末尾
while (fast != NULL && fast->next != NULL) {
slow = slow->next; // 慢指针每次移动一步
fast = fast->next->next; // 快指针每次移动两步
}
return slow; // 慢指针指向中间节点
}
//反转链表
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* n1, *n2, *n3;
n1 = NULL;
n2 = head;
if (n2)
n3 = n2->next;
while (n2) {
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3)
n3 = n3->next;
}
return n1;
}
bool chkPalindrome(ListNode* A) {
// write code here
struct ListNode*mid=middleNode(A);
struct ListNode*rmid=reverseList(mid);
while(rmid&&A)
{
if(rmid->val!=A->val)
return false;
rmid=rmid->next;
A=A->next;
}
return true;
}
};
实现一个函数,复制一个含有随机指针的链表。随机指针可以指向链表中的任何节点或为空。
常规链表的复制很简单,但随机指针的存在使得问题复杂化。因为随机指针可能指向尚未复制的节点。我们可以通过以下三步解决:
struct Node* copyRandomList(struct Node* head) {
//拷贝节点插到原节点后边
struct Node*cur=head;
while(cur)
{
struct Node* copy=(struct Node*)malloc(sizeof(struct Node));//分配内存
copy->next=cur->next;
cur->next=copy;
copy->val=cur->val;
cur=copy->next;//cur走到原链表的下一个
}
//控制random
cur=head;
while(cur)
{
struct Node* copy = cur->next;
if(cur->random==NULL)//不要写成random==NULL
{
copy->random=NULL;
}
else
{
copy->random=cur->random->next;//核心代码
}
cur=copy->next;
}
//把拷贝链表尾插起来
struct Node* copyhead=NULL,*copytail=NULL;
cur=head;
while(cur)
{
struct Node*copy=cur->next;
if(copytail==NULL)
{
copyhead=copytail=copy;
}
else
{
copytail->next=copy;
copytail=copytail->next;
}
cur=copy->next;
}
return copyhead;
}