赞
踩
dhttps://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca
时间复杂度:O(n), 遍历一次链表
空间复杂度:O(1)
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { ListNode *pre = nullptr; ListNode *cur = pHead; ListNode *nex = pHead; while(cur != nullptr){ nex = cur->next; cur->next = pre; pre = cur; cur = nex; } return pre; // 返回反转后的链表的头结点 } };
先用一个vector将单链表的指针都存起来,然后再构造链表。
时间复杂度:O(n)
空间复杂度:O(n), 因为用了一个vector来存单链表
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { if (!pHead) return nullptr; vector<ListNode*> v; while(pHead){ v.push_back(pHead); pHead = pHead->next; } reverse(v.begin(),v.end()); // 反转vector // 构造链表,以head为头结点。cur为head的复制结点,作为当前结点,用于构建链表。 ListNode *head = v[0]; ListNode *cur = head; for(int i=0; i<v.size(); i++){ cur->next = v[i]; // 当前(cur)节点的下一个指针指向下一个节点 cur = cur->next; // 当前(cur)节点后移 } cur->next = nullptr; // 切记最后一个节点的下一个指针指向nullptr return head; // 返回反转后的链表的头结点 } };
时间复杂度:O(n),其中 n是链表的长度。需要对链表的每个节点进行反转操作。
空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { if(pHead==nullptr || pHead->next==nullptr ) return pHead; ListNode *reverseListHead = ReverseList(pHead->next); pHead->next->next = pHead; pHead->next = nullptr; return reverseListHead; // 返回反转后的链表的头结点 } };
这里递归不好理解,下面是详细的:
https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/
/** * 以链表1->2->3->4->5举例 */ public ListNode reverseList(ListNode* head) { if (head == null || head.next == null) { /* 直到当前节点的下一个节点为空时返回当前节点 由于5没有下一个节点了,所以此处返回节点5 */ return head; /* 第一轮(最上层)出栈:传入的head为5,由于head.next为空,于是返回该节点5, reverseListHead接收该结点5 */ } //递归,一直递归到链表的最后一个结点,该结点就是反转后的头结点reverseListHead,即节点5。 ListNode *reverseListHead = reverseList(head.next); // 递归入栈,共5层栈。 /* 继上面的第一轮出栈后,此时head为4,于是 第二轮(第二层)出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4, 把当前节点的子节点的子节点指向当前节点 此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null 此时链表为1->2->3->4<-5 返回节点5 第三轮(第三层)出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3, 此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null 此时链表为1->2->3<-4<-5 返回节点5 第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2, 此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null 此时链表为1->2<-3<-4<-5 返回节点5 第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1, 此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null 此时链表为1<-2<-3<-4<-5 返回节点5 出栈完成,最终头节点5->4->3->2->1 */ head.next.next = head; head.next = null; return reverseListHead; // 返回反转后的链表的头结点 }
/** * 以链表1->2->3->4->5举例 */ public ListNode reverseList(ListNode* head) { if (head == null || head.next == null) { /* 递归的“递”过程的终止条件。从 'return head;' 开始,“归”已经开始了。 “递”到最后,到达结点5,由于结点5没有下一个节点了(即5.next==null),所以此处返回节点5,即“归”5,由reverseListHead接收节点5。 */ return head; } //递归,一直递归到链表的最后一个结点,该结点就是反转后的头结点reverseListHead,即节点5。 ListNode *reverseListHead = reverseList(head.next); /* 第一轮出栈,head为5,head.next为空,返回节点5 第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4, 把当前节点的子节点的子节点指向当前节点 此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null 此时链表为1->2->3->4<-5 返回节点5 第三轮出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3, 此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null 此时链表为1->2->3<-4<-5 返回节点5 第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2, 此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null 此时链表为1->2<-3<-4<-5 返回节点5 第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1, 此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null 此时链表为1<-2<-3<-4<-5 返回节点5 出栈完成,最终头节点5->4->3->2->1 */ head.next.next = head; head.next = null; return reverseListHead; // 返回反转后的链表的头结点 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。