给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1]
和之前逆置链表的思路比较类似,设置虚拟头结点,然后设置temp,之后交换位置即可
错误代码:
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
ListNode* VirtualHead = new ListNode(0);
VirtualHead->next = head;
ListNode* left,right,temp;
left = VirtualHead->next;
while(left->next != NULL)
{
right = left->next;
VirtualHead->next = right;
left->next =right->next;
right->next = left;
VirtualHead = left;
}//错误代码,不应该在while中修改virtualhead,这样会导致头结点丢失
}
};
正确代码,注意事项在注释里
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
if(head == NULL || head->next == NULL) return head;//先提前判断是否非空
ListNode* VirtualHead = new ListNode(0);
VirtualHead->next = head;
ListNode* left,*right,*temphead;//注意*号两个都要打上
left = VirtualHead->next;
right = left->next;
temphead = VirtualHead;
while(temphead->next != NULL && temphead->next->next != NULL)
{
left = temphead->next;
right = left->next;//注意这个放前面,防止出现错误,具体原因不清楚,可能是防止指向位置空间
temphead->next = right;
left->next =right->next;
right->next = left;
temphead = left;
}
ListNode* result = VirtualHead->next;
return result;
}
};
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1 输出:[]
示例 3:
输入:head = [1,2], n = 1 输出:[1]
主要思路,人为制造长度为n的尺子
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == NULL || head->next == NULL) return NULL;
ListNode* virtualhead =new ListNode(0);
virtualhead->next = head;//注意使用虚拟头节点来确定真正的头节点,因为删除的可能就是头节点
ListNode *fast,*slow;
fast = head;
while(n--)
{
fast = fast->next;
}
slow = virtualhead;
while(fast != NULL)//看不清可以画图理解
{
fast = fast->next;
slow = slow->next;
}//此时slow指向目标的前一个结点
slow->next = slow->next->next;
return virtualhead->next;
}
};
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
图示两个链表在节点 c1
开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Intersected at '8' 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Intersected at '2' 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 这两个链表不相交,因此返回 null 。
这不考研原题吗,某一年的数据结构代码大题
思路就是先统计两个链表的长度,得到差值,然后调整起始位置,一起向后,直到遇到相同的结点为止。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lengthA = 0 ,lengthB = 0;
ListNode *nodeA = headA,*nodeB = headB;
while(nodeA != NULL)
{
nodeA = nodeA->next;
lengthA++;
}
while(nodeB != NULL)
{
nodeB = nodeB->next;
lengthB++;
}
//注意这里我们让最长的那个是A,短的是B,方便后面处理
if(lengthB > lengthA)
{
swap(lengthA,lengthB);
swap(headA,headB);
}
nodeA = headA;
nodeB = headB;
int cha = lengthA - lengthB;
while(cha--)
{
nodeA = nodeA->next;
}
while(nodeA != NULL)
{
if(nodeA == nodeB)
{
return nodeA;
}//注意先判断再提交
nodeA = nodeA->next;
nodeB = nodeB->next;
}
return NULL;
}
};
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:返回索引为 0 的链表节点 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:返回 null 解释:链表中没有环。
这题很复杂,需要从数学上进行理解,看随想录的PPT代码随想录
不看解析我很难想出来
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next == NULL) return NULL;
ListNode *fast = head,*slow = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow ->next;
if(fast == slow) break;
}
if(fast == NULL || fast->next == NULL) return NULL;
ListNode *newnode =head;
while(fast != newnode)
{
fast = fast->next;
newnode = newnode->next;
}
return fast;
}
};