leetcode day5 -- Reorder List && Linked List Cycle II

1、



Reorder List

Given a singly linked list LL0L1→…→Ln-1Ln,

reorder it to: L0LnL1Ln-1L2Ln-2→…

You must do this in-place without altering the nodes‘ values.

For example,

Given {1,2,3,4}, reorder it to {1,4,2,3}.

分析:翻转链表是很常见的题目,这种翻转是第一次见。一开始的想法是双指针法,头一个指针,尾一个指针,进行合并,但是链表是单向的,尾指针不能前移,此种方法不行。然后想到先找到中间结点,将中间结点后部分链表翻转,再进行两个链表的交叉合并,此种方法可行。

代码如下:

class Solution {
public:
    void reorderList(ListNode *head) {
        if(!head){
			return;
		}
		ListNode* midNode = findMidNode(head);
		ListNode* postListHead = midNode->next;
		midNode->next = NULL;
		postListHead = reverseList(postListHead);
		crossMergeList(head,postListHead);
    }
private:
	ListNode* findMidNode(ListNode *head){
		if(!head){
			return NULL;
		}
		ListNode* pNode1 = head;
		ListNode* pNode2 = head->next;
		if(!pNode2){
			return pNode1;
		}else{
			pNode2 = pNode2->next;
		}
		while(pNode2!=NULL){
			pNode2 = pNode2->next;
			if(pNode2!=NULL){
				pNode2 = pNode2->next;
			}
			pNode1 = pNode1->next;
		}
		return pNode1;
	}
	ListNode* reverseList(ListNode* head){
		ListNode* preNode = NULL;
		ListNode* curNode = head;
		while(curNode!=NULL){
			ListNode* tempNode = curNode->next;
			curNode->next = preNode;
			preNode = curNode;
			curNode = tempNode;
		}
		return preNode;
	}
	//将头指针为head2的链表交叉连接在头指针为head1的后面
	void crossMergeList(ListNode* head1,ListNode* head2){
		ListNode* tempNode1 = head1;
		ListNode* tempNode2 = head2;
		while(head1!=NULL && head2!=NULL){
			tempNode1 = head1->next;
			tempNode2 = head2->next;
			head1->next = head2;
			head2->next = tempNode1;
			head1 = tempNode1;
			head2 = tempNode2;
		}
	}
};

2、Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:

Can you solve it without using extra space?

分析:乍看是一个很常见的和链表中环有关系的题目,但是细想很难,很容易使用双指针法判断链表是否有环和环的大小,但是要求环的起始点,却不好想。参考:

http://blog.csdn.net/sysucph/article/details/15378043,大致思路是:首先利用双指针法,一个指针一次走一步,一个指针一次走两步,如果有环,两个指针会相遇,如果没有则不会相遇。如果相遇此时,将一个指针置于链表头,另一个指针在相遇点,两个指针每次都走一步,直到两个指针相遇,此时结点为环的起点。

至于为什么这样就是环的起点呢,我简要证明了一下。

代码如下:

class Solution {
public:
	ListNode *detectCycle(ListNode *head) {
		if(!head){
			return NULL;
		}
		ListNode* pNode1 = head;
		ListNode* pNode2 = head;
		ListNode* firstMeetNode = NULL;
		while(pNode2!=NULL){
			pNode1 = pNode1->next;
			pNode2 = pNode2->next;
			if(pNode2 != NULL){
				pNode2 = pNode2->next;
			}
			if(pNode1!=NULL && pNode1 == pNode2) {
				firstMeetNode = pNode2;
				break;
			}
		}
		if(!firstMeetNode){
			return NULL;
		}else{
			pNode1 = head;
			while(pNode1 != pNode2){
				pNode2 = pNode2->next;
				pNode1 = pNode1->next;
			}
			return pNode1;
		}
	}
};

3、Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up:Can you solve it without using extra space?

分析:做完上一题这一题就很简单了,就是要注意两个指针的初始值和后续判断问题。

代码如下:

class Solution {
public:
    bool hasCycle(ListNode *head) {
		if(!head){
			return NULL;
		}
		ListNode* pNode1 = head;
		ListNode* pNode2 = head;
		while(pNode2!=NULL){

			pNode1 = pNode1->next;
			pNode2 = pNode2->next;
			if(pNode2 != NULL){
				pNode2 = pNode2->next;
			}
			if(pNode1 != NULL && pNode1 == pNode2){
				return true;
			}
		}
		return false;
	}
};



				
时间: 2024-10-11 17:51:42

leetcode day5 -- Reorder List && Linked List Cycle II的相关文章

leetcode:142. Linked List Cycle II(Java)解答

转载请注明出处:z_zhaojun的博客 原文地址:http://blog.csdn.net/u012975705/article/details/50412899 题目地址:https://leetcode.com/problems/linked-list-cycle-ii/ Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return

LeetCode Linked List Cycle II

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode* fast = head; ListNode* slow = head;

LeetCode: Linked List Cycle II [142]

[题目] Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? [题意] 给定一个单向链表,如果链表有环,则返回环开始的位置. [思路] 仍然是维护两个指针, p1, p2, p1每次走一步, p2每次走两步 假设进入环之前要走X步,环长为y步,p2第

[LeetCode 题解]: Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up:Can you solve it without using extra space? 题意: 给定一个链表,找到环起始的位置.如果环不存在,返回NULL. 分析: (1)首先要判断该链表是否有环.如果没有环,那么返回NULL. (2)其次,当已知环存在后,寻找环起始的位置. 思路: (

[LeetCode][JavaScript]Linked List Cycle II

Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note: Do not modify the linked list. Follow up:Can you solve it without using extra space? https://leetcode.com/problems/linked-list-

Java for LeetCode 142 Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? 解题思路,本题和上题十分类似,但是需要观察出一个规律,参考LeetCode:Linked List Cycle II JAVA实现如下: public ListNode detectCycle(Li

【Leetcode】Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? 思路:由[Leetcode]Linked List Cycle可知,利用一快一慢两个指针能够判断出链表是否存在环路.假设两个指针相遇之前slow走了s步,则fast走了2s步,并且fast已经在长度

LeetCode OJ - Linked List Cycle II

题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? 解题思路: 设置两个指针slow和fast,从head开始,slow一次一步,fast一次两步,如果fast能再次追上slow则有圈. 设slow走了n步,则fast走了2*n步,设圈长度m

【leetcode刷题笔记】Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up:Can you solve it without using extra space? 判断一个链表是否有环. 题解: 设置两个指针p1和p2: p1每次走一步,p2每次走两步,如果在这个过程中,p2为空,则没有环:否则两个指针必然相遇,则有环: 接下来找环的起点,将p1挪动到链表起始,