将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度
,空间复杂度
。
例如:
给出的链表为
,
,
返回
.
例如:
给出的链表为
返回
数据范围: 链表长度
,
,链表中每个节点的值满足
要求:时间复杂度
,空间复杂度
进阶:时间复杂度
,空间复杂度
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @param m int整型 * @param n int整型 * @return ListNode类 */ #include <stdlib.h> struct ListNode *reverseBetween(struct ListNode *head, int m, int n) { // write code here //增加一个头结点方便操作 struct ListNode * L=(struct ListNode*)malloc(sizeof(struct ListNode)); L->next=head; struct ListNode *pre = L; // 记录弟m的前一个结点 struct ListNode *end = head; // 记录弟n的后一个结点 struct ListNode *p1 = head;//弟m个结点 struct ListNode *p2; struct ListNode *p3; int i = 1; while (p1 && i < m)//找到弟m个结点 { /* code */ pre = p1; p1 = p1->next; i++; } // printf("%d\n",p1->val); i = 0; while (end && i < n)//找到n的下一个结点 { end = end->next; i++; } // printf("%d\n",end->val); //进行区间翻转 struct ListNode *begin=p1; p2 = p1->next; p3 = p2; i = m; while (p2 && i < n) { p3 = p3->next; p2->next = p1; p1 = p2; p2 = p3; i++; } begin->next=end;//把原本第一个结点接到弟n个结点之后 pre->next=p1;//反转后的弟n个结点连接弟m的前一个 return L->next; }
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) { if (head == NULL || m == n) return head; struct ListNode dummy; dummy.next = head; struct ListNode* pre = &dummy; for (int i = 1; i < m; i++) { pre = pre->next; } struct ListNode* start = pre->next; struct ListNode* then = start->next; for (int i = 0; i < n - m; i++) { start->next = then->next; then->next = pre->next; pre->next = then; then = start->next; } return dummy.next; }
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @param m int整型 * @param n int整型 * @return ListNode类 */ struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { struct ListNode *prev = NULL; struct ListNode *next = NULL; struct ListNode *phead = head; struct ListNode *reverseBegin = NULL; struct ListNode *reverseEnd = NULL; int i = 1; if (NULL == head || NULL == head->next || m >= n) { return head; } while(NULL != head) { if (i < m) { /* 记录翻转链表开始的地方 */ reverseBegin = head; head = head->next; } /* 翻转链表结束后 */ else if (i > n) { head = head->next; } else { if (i == m) { /* 翻转链表结束的地方是原翻转链表开头 */ reverseEnd = head; } /* 对需要翻转的节点进行翻转 */ next = head->next; head->next = prev; prev = head; head = next; /* 翻转链表最后一个节点时拼接前后的链表 */ if (i == n) { /* 考虑翻转链表从第一个结点开始 */ if (1 == m) { phead = prev; /* 考虑翻转链表后面没有结点的情况 */ if (NULL != head) { reverseEnd->next = head; } } else { reverseBegin->next = prev; reverseEnd->next = head; } } } i++; } return phead; }
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { // write code here if (head->next == NULL || head == NULL) { return head; } else if (m == n) { return head; } struct ListNode* temp = NULL; struct ListNode* prehead1 = NULL; struct ListNode* prehead2 = NULL; struct ListNode* prehead = NULL; int i = 0, j = 0; prehead = head; while (i < m - 1) { prehead1 = head; head = head->next; i++; } while (i < n) { temp = head->next; head->next = prehead2; prehead2 = head; head = temp; i++; } if (prehead1 == NULL) { prehead1 = prehead2; while (prehead2->next != NULL) { prehead2 = prehead2->next; } prehead2->next = temp; return prehead1; } else { prehead1->next = prehead2; } while (prehead2->next != NULL) { prehead2 = prehead2->next; } prehead2->next = temp; return prehead; }
struct ListNode* GetListNode(struct ListNode* head, int m) { struct ListNode *p1; p1 = head; while(--m>0) p1 = p1->next; return p1; } struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { struct ListNode *res, *buffer; if(head == NULL || head->next == NULL || m==n) return head; if(m==1) { int i,j; for(i=0;i<n/2;i++) { j = GetListNode(head,i+1)->val; GetListNode(head,i+1)->val = GetListNode(head,n-i)->val; GetListNode(head,n-i)->val = j; } return head; } res = reverseBetween(head, m, n-1); buffer = GetListNode(head,n); GetListNode(head,n-1)->next = buffer->next; buffer->next = GetListNode(head,m); GetListNode(head,m-1)->next = buffer; return res; }
#include <stdlib.h> struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { typedef struct ListNode list; //如果是从首节点开始反转,则没有上一个节点需要记录,所以需要创建一个首节点的上节点来保证程序正确。 list* empty =(list*)malloc(sizeof(list)); empty->val =0; empty->next =head; int i =0; list* p1 =empty; for(i=0;i<m-1;i++) { p1=p1->next; } //记录开始节点 list* start = p1->next; list* new_node =start; list* p2 =NULL; for(i = m-1;i<n;i++) { list* tmp = new_node->next; new_node->next =p2; p2 =new_node; new_node =tmp; } //链表反转结束,开始区间反转 p1->next =p2; start->next = new_node; //如果是从头反转,头节点不再是输入的节点 list* new_head =empty->next; free(empty); return new_head; }
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { int x = m;//记录起始位置 int c = n-m;//记录反转次数 if(c<=0 || head==NULL)//当不反转或空表时直接返回 { return head; } struct ListNode* p = head; //用于记录区间前一个元素 struct ListNode* first = head; //用于记录区间第一个元素 if(x>1)//当区间外存在前一个元素时 { while(m-2)//将p移动到区间前一个元素位置 { p = p->next; m--; } first = p->next;//移动到区间第一个位置 } struct ListNode* left = first; //记录左边的元素(目标元素) struct ListNode* right = first->next; //记录右边的元素(移动元素) while(c)//反转次数 { first->next = right->next;//使用区间第一个元素的next,记录移动元素下个元素的地址 right->next = left; //反向连接 left = right; //目标元素向右移动 right = first->next; //移动元素向右移动 c--; } if(x<=1)//当区间外不存在前一个元素时,头节点为left { return left; }else {//存在前一个元素时,头节点为head p->next = left;//前一个元素的next指向区间最后一个元素 return head; } }
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { struct ListNode phead; //设置虚拟头结点 phead.next = head; struct ListNode *next = NULL; //反转的下一个节点 struct ListNode *prior = NULL; //反转的前一个节点 struct ListNode *start = &phead; //反转链表第一个节点 struct ListNode *end = NULL; //反转链表最后一个节点 struct ListNode *left = NULL; //反转链表前的一个节点 struct ListNode *right = NULL; //反转链表后的一个节点 int i = 0; for (i=0; i<m-1; ++i) //找到链表反转的前一个节点 { start = start->next; //start的起始值:并不是整个链表的第一个节点 } head = right = left = start->next; //链表反转的第一个节点 for (i=m; i<n; ++i) //找到链表反转的最后一个节点 { right = right->next; } end = right->next; //反转链表结束后的节点 right->next = NULL; //将反转部分断开 while (head!=NULL) { next = head->next; //存储下一个节点 head->next = prior; //反转 prior = head; //存储前一个节点 head = next; //移到下一个节点 } start->next = right; //将断开的链表接上 left->next = end; //将断开的链表接上 return phead.next; }