文章目录
一.链表反转
/* 初始化:3个指针
1.pre指针指向已经反转好的链表的最后一个节点,最开始没有反转,所以指向nullptr
2.cur指针指向待反转链表的第一个节点,最开始第一个节点待反转,所以指向head
3.nex指针指向待反转链表的第二个节点,目的是保存链表,因为cur改变指向后,后面的链表则失效了,所以需要保存
循环执行以下三个操作:
1.nex = cur->next,保存作用
2.cur->next = pre,未反转链表的第一个节点的下个指针指向已反转链表的最后一个节点
3.pre = cur,cur = nex;指针后移,操作下一个未反转链表的下一个节点。
循环条件:cur!=nullptr
循环结束后,cur为nullptr,返回pre,即为反转后的头节点。
*/
class solution
{
public:
ListNode * Reverselist(ListNode * phead)
{
ListNode *pre = nullptr;
ListNode *cur = phead;
ListNode *nex = nullptr;
while(cur)
{
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
return pre;
}
};
时间复杂度:O(n)
空间复杂度:O(1)
1.1链表内指定区间反转
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
if(head == NULL || head->next == NULL || m <= 0 || n <= 0 || m >= n)
{
//入参判断
return head;
}
if(head->next->next == NULL)
{
//考虑只有两个节点的反转
struct ListNode *ptemp = head->next;
ptemp->next = head;
head->next = NULL;
head = ptemp;
return head;
}
struct ListNode *phead = (struct ListNode *)malloc(sizeof(struct ListNode));
phead->val = 0;
phead->next = head;
struct ListNode *pre = NULL;
struct ListNode *plast = NULL;//定义快慢指针
int i;
if(m == 1)
{
//考虑从第一个节点开始反转,pre要从Phead节点开始
i = 1;
pre = phead;
plast = head;
}else
{
for(i = 2; i < m; i++)
{
head = head->next;
}
pre = head;
head = head->next;
plast = head;
}
for(; i < n; i++)
{
//反转
struct ListNode *ptemp = pre->next;
head = head->next;
plast->next = head->next;
pre->next = head;
head->next = ptemp;
head = plast;
}
head = phead->next;
free(phead);
phead = NULL;
return head;
}
1.2 链表中的节点每k个一组翻转
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
struct ListNode* tail=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->next=head;
struct ListNode* pre=tail;
struct ListNode* cur=tail->next;
struct ListNode* tmp=NULL;
int i;
for(i=