LeetCode
206.Reverse Linked List
24.Swap Nodes in Pairs
141.Linked List Cycle
142.Linked List Cycle II
25.Reverse Nodes in k-Group
LeetCode206 反转链表
https://leetcode-cn.com/problems/reverse-linked-list/
题目描述:
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
解题思路:
1.迭代方法:在原链表之前新建一个newHead,因为首节点会变,然后从head开始,将之后的一个节点移到newHead之后,重复此步骤直到head成为末节点为止。
2.递归方法 (套路解决递归问题 )
解法一:使用迭代
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *newHead = NULL; //前指针节点
//每次循环,都将当前节点指向它前面的节点,然后当前节点和前节点后移
while (head) {
ListNode *temp = head->next; //临时节点,暂存当前节点的下一节点,用于后移
head->next = newHead; //将当前节点指向它前面的节点
newHead = head; //前指针后移
head = temp; //当前指针后移
}
return newHead;
}
};
解法二:使用递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head || !head->next)
return head;
struct ListNode *newhead = reverseList(head->next); //newhead指针记录链表末尾节点
head->next->next = head;
head->next = NULL;
return newhead;
}
};
LeetCode24 两两交换链表中的节点
https://leetcode-cn.com/problems/swap-nodes-in-pairs/
题目描述:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
解题思路:
1.使用迭代
2.使用递归 (套路解决递归问题 )
解法一:使用迭代
//使用3个指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head == NULL || head->next == NULL)return head;
ListNode* first, *second, *current;
first = head;//指向表头
second = head->next;//指向表的第二个位置
//第一次交换
first->next = second->next;
second->next = first;//此时first在second后面
ListNode* result = second;//结果
do{
first = first->next;//向后移一个
if(first == NULL || first->next == NULL){//判断后面是否有两个
break;
}
second = second->next;//后移一个位置
current = second;//保存当前的位置,用于后面交换
second = second->next->next;//后移两个位置,到first后面
//交换
first->next = second->next;
current->next = second;
second->next = first;
}while(1);
return result;
}
};
解法二:使用递归:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
//终止条件:链表只剩一个节点或者没节点了,没得交换了。返回的是已经处理好的链表
if(head == NULL || head->next == NULL){
return head;
}
//一共三个节点:head, next, swapPairs(next.next)
//下面的任务便是交换这3个节点中的前两个节点
ListNode *next = head->next;
head->next = swapPairs(next->next);
next->next = head;
//根据第二步:返回给上一级的是当前已经完成交换后,即处理好了的链表部分
return next;
}
};
LeetCode141 环形链表
https://leetcode-cn.com/problems/linked-list-cycle/
题目描述:
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例:
解题思路:
1.硬做,判断遍历0.5秒后末尾指针是否为NULL。
2.set判重,时间复杂度O(n)。
3.快、慢指针,时间复杂度O(n),但空间复杂度较小。
解法三:
//快、慢指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *fast = head;
ListNode *slow = head;
while(slow != NULL && fast != NULL && fast->next != NULL) {
slow = slow->next; //慢指针每次后移一步
fast = fast->next->next; //快指针每次后移两步
if(slow == fast)
return true;
}
return false;
}
};