NC4. 判断链表是否有环
题目描述
难度 的⭐
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
你能给出空间复杂度为O(1)的解法么?
思路
使用快指针、慢指针方法,快指针一次移动两格,慢指针一次移动一格,总之,如果有环的话,它俩早晚有一天会碰上。
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
};
NC3. 链表环的入口节点
难度 ⭐⭐
题目描述
对于一个给定的链表,返回环的入口节点,如果没有环,返回null
拓展:
你能给出不利用额外空间的解法么?
思路
这道题是上一道题的扩展:如果知道有环,那么入口的位置在哪呢?可以先画一个图:
假设图中存在环且快慢指针在z处相遇,此时慢指针走了a+b,快指针走了a+(b+c)*n,推出a=n(b+c)-b,因此让两个指针分别从起始点X和相遇点Z以相同速度前进,两个指针再次相遇的位置即为环的入口节点Y。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode *slow2 = head;
while(slow && slow2){
if(slow == slow2)
return slow;
slow = slow->next;
slow2 = slow2->next;
}
}
}
return NULL;
}
};
NC53. 删除链表的倒数第n个节点
难度⭐⭐
题目描述
给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针。
例如,
给出的链表为: 1→2→3→4→5, n= 2
删除了链表的倒数第 n 个节点之后,链表变为1→2→3→5.
思路
为了找到“倒数第n个”节点,可以让一个快指针先出发n步。同时考虑到删除第一个节点的情况,因此应该增加一个哨兵“头”。
class Solution {
public:
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
ListNode* head0 = new ListNode(-1);
head0->next = head;
ListNode* fast = head0;
ListNode* slow = head0;
for(int i = 0;i<n;i++)
fast = fast->next;
while(fast->next){
fast = fast->next;
slow = slow->next;
}
cout<<slow->val;
if(slow->next){
ListNode* tmp_next_next = slow->next->next;
slow->next = tmp_next_next;
return head0->next;
}
if(slow){
slow->next = NULL;
return head0->next;
}
return head0->next;
}
};