206. 反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
法1:递归调用(不易理解),o(1)
调用自身来实现
//法3:递归调用(难以理解) struct ListNode* reverseList(struct ListNode* head) { if(head == NULL) return NULL; if(head->next == NULL) return head; // NOW -> NEXT(node)->NULL //改为 NULL <- NOW <-NEXT NULL struct ListNode* NOW = head; struct ListNode* NEXT = NOW->next; struct ListNode* rear = (struct ListNode*) reverseList(NEXT); //指向最后一个节点 NEXT ->next = NOW; NOW ->next = NULL; return rear; }
法2:迭代调用:o(1)
好理解,直接实现也简单
//法2:o(1)空间 直接 链表交换法:迭代法: struct ListNode* reverseList(struct ListNode* head) { if(head == NULL || head->next == NULL) //空链表或者只有一个节点 return head; struct ListNode* lastp = NULL; struct ListNode* nowp = head; struct ListNode* nextp = head->next; //NULL <- A B -> C -> NULL // lastp nowp nextp // nowp->next = nextp //NULL <- A <- B C -> NULL // lastp <- nowp nextp // (改为nowp->next = lastp) //NULL <- A <- B C -> NULL //下一跳 // lastp nowp nextp while(nextp !=NULL) { nowp->next = lastp; lastp = nowp; nowp = nextp; nextp = nextp->next; } nowp->next = lastp; return nowp; }
法3:常规做法,o(n)
用数组先保存,然后再反转链表
//法1:用 数组空间o(n) 来实现链表反转 struct ListNode* reverseList(struct ListNode* head) { if(head == NULL) return NULL; struct ListNode* p = head; int i = 0; int BUF[10000]; int len=0; while(p != NULL) { BUF[i] = p->val; i++; p=p->next; } len = i; printf("len = %d\n",len); struct ListNode* head2 = (struct ListNode*)malloc(sizeof(struct ListNode)); p = head2; for(i = len-1;i>=0;i--) { p->val = BUF[i]; if(i == 0) //最后一个指向NULL的不能申请内存,否则就输出0,多了一个元素 { p->next = NULL; break; } p->next = (struct ListNode*)malloc(sizeof(struct ListNode)); p = p->next; } return head2; }
206
.
反转链表