链表中环的入口
题目:给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next
指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null
。
主要思想:运用快慢指针
题解:分析题目就可以知道,首先第一步是先判断链表是否有环,用到快慢指针(快指针每次都比慢指针多走一步),当快慢指针重合时,即有环,返回其重合的节点。
第二步就是分析链表环中有多少个节点,因为环是闭合的,所以可以通过返回的环中节点来计算环有多少个节点n。
第三步就是,定义一个前指针和一个后指针,前指针先走n步,然后和后指针一起遍历,当两指针重合时,重合节点为环的入口节点。
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next == NULL) return NULL;
ListNode *front = MeetingNode(head);
if(front == NULL) return NULL;
ListNode *behind = front;
int n = 1;
front = front->next;
//计算环中节点的个数
while(front != behind)
{
front = front->next;
n++;
}
front = head;
behind = head;
for(int i = 0; i < n; i++)
{
front = front->next;
}
while(behind != front)
{
front = front->next;
behind = behind->next;
}
return behind;
}
//判断链表是否有环存在
ListNode *MeetingNode(ListNode *head)
{
if(head == NULL || head->next == NULL) return NULL;
ListNode *slow = head;
ListNode *farst = head->next;
while(farst != NULL)
{
if(slow == farst) return slow;
slow = slow->next;
farst = farst->next;
if(farst == NULL) return NULL;
else farst = farst->next;
}
return NULL;
}
链表反转
题目:给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
题解:第一步,建立一个伪头指针,其下一个指针指向头指针(这能使得头指针能像其他中间节点一样处理),找到需要反转的链表部分的前部份和后部分,分辨用一个start指针和end指针记录。
第二步:反转链表,利用三个指针,一个是前指针front,另一个头指针head,最后一个是尾指针p
将头指针指向end,而头指针head的next指向front反向,最后head和p均向后移动。
最后:当p指针与end指针重合时,退出反转,start指针的next指向head,返回behead->next,即为反转后的指针。(注意释放申请的behead指针)
ListNode* reverseBetween(ListNode* head, int left, int right) {
if(head == NULL || head->next == NULL || right == left) return head;
ListNode *behead = new ListNode(0, NULL);
behead->next = head;
ListNode *start = head;
ListNode *end = NULL;
ListNode *p = head;
int n = 1;
while(n != right && p != NULL)
{
if(n == left - 1) start = p;
n++;
p = p->next;
}
if(p == NULL) end = NULL;
else end = p->next;
if(left == 1) start = behead;
ListNode *front = start->next;
head = front->next;
front->next = end;
p = head->next;
while(p != end)
{
head->next = front;
front = head;
head = p;
p = p->next;
}
head->next = front;
start->next = head;
head = behead->next;
delete behead;
return head;
}