将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度
,空间复杂度
。
例如:
给出的链表为
,
,
返回
.
例如:
给出的链表为
返回
数据范围: 链表长度
,
,链表中每个节点的值满足
要求:时间复杂度
,空间复杂度
进阶:时间复杂度
,空间复杂度
{1,2,3,4,5},2,4{1,4,3,2,5}{5},1,1{5}
{1,2,3,4},1,4{4,3,2,1}struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
struct ListNode* pm_prev = NULL;
struct ListNode* pm = NULL;
struct ListNode* pn = NULL;
struct ListNode* pn_next = NULL;
struct ListNode* p_last = NULL;
struct ListNode* p_next = NULL;
struct ListNode* p_cur = NULL;
int i = 0;
if (!head) {
return NULL;
}
if (m > n) {
return NULL;
}
p_cur = head;
for (i=1; p_cur; i++) {
p_next = p_cur->next;
if (pm) {
// reverse
if (i > m) {
p_cur->next = p_last;
}
}
if (i == m) {
pm = p_cur;
pm_prev = p_last; // maybe NULL
}
if (i == n) {
pn = p_cur;
pn_next = p_next; // maybe NULL
}
if (pn) {
//fond n, end
pm->next = pn_next;
if (pm_prev) {
pm_prev->next = pn;
} else {
pm->next = pn_next;
return pn;
}
return head;
}
p_last = p_cur;
p_cur = p_next;
}
return head;
} /**
* 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 ) {
// write code here
struct ListNode*start=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*last=(struct ListNode*)malloc(sizeof(struct ListNode));
start->next=head;
struct ListNode*p=head;
while(p->next!=NULL)
{
p=p->next;
}
last->next=p->next;
p->next=last;
struct ListNode*pre=start;
struct ListNode*first=NULL;
struct ListNode*second=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*third=(struct ListNode*)malloc(sizeof(struct ListNode));
for(int i=0;i<m-1;i++)
{
pre=pre->next;
}
second=pre->next;
struct ListNode*q=second;
struct ListNode*rear=pre;
for(int i=m-1;i<n+1;i++)
{
rear=rear->next;
}
while(second!=rear)
{
third=second->next;
second->next=first;
first=second;
second=third;
}
pre->next=first;
q->next=rear;
struct ListNode*l=start;
while(l->next->next!=NULL)
{
l=l->next;
}
l->next=NULL;
if(m==1)
{
head=first;
}
return head;
}
感觉官方视频那个视频有点看不懂,我直接把所需要的部分链表翻转再接回原链表,但是这样做,需要考虑m=1的特殊情况,不知道也采用这种暴力思路的码友们有没有更好的思路来合并这种特殊情况
/**
* 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;
}