题目描述
将一个链表m位置到n位置之间的区间反转,要求时间复杂度 O(n),空间复杂度O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4
返回1→4→3→2→5→NULL.
注意:
给出的m,n满足以下条件:
1≤m≤n≤链表长度
(参考杭电 De梦的题解)
方法一:直接暴力求解
求解思路
对于反转链表,我们在求解的时候,可以引入一个next节点,然后对链表的局部进行反转。这样暴力求解,即可求出答案。
解题代码
import java.util.*;
public class Solution {
// 参考De梦代码
public ListNode reverseBetween (ListNode head, int m, int n) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
//pre结点走到m的前一个结点
for(int i=0;i<m-1;i++){
pre = pre.next;
}
//rightnode走到n的结点
ListNode rigthNode = pre;
for(int i=0;i<n-m+1;i++){
rigthNode = rigthNode.next;
}
//取子链表
ListNode leftNode = pre.next;
ListNode cur = rigthNode.next;
//分离子链表
pre.next=null;
rigthNode.next=null;
//反转局部链表,参考De梦的code
reverseLinkedList(leftNode);
//拼接链表
pre.next = rigthNode;
leftNode.next = cur;
return dummyNode.next;
}
//反转局部链表
private void reverseLinkedList(ListNode head){
ListNode pre = null;
ListNode cur = head;
while(cur!=null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
}
}复杂度分析
时间复杂度:O(N),N为节点的个数
空间复杂度:O(1),没有使用额外的内存空间
方法二:递归的思想求解
求解思路
对于反转链表,我们使用递归的思想,将大问题转换为小问题,然后进行相应的求解即可。对于递归过程,判断n的数值,当n为1时返回head指针,否则进行递归,并且反转链表,最后进行拼接,返回拼接之后的链表。
解题代码
class Solution {
public:
ListNode* tmp = NULL;
ListNode* reverseBetween(ListNode* head, int m,int n){
if( m == 1) return reverse(head, n);
ListNode* p = reverseBetween(head->next, m-1,n-1); // m,n在子问题中要减1
head->next = p; //拼接反转之后的部分
return head;
}
ListNode* reverse(ListNode* head,int n)
{//反转链表,递归的思想,参考贵州大学的漫漫云天自翱翔的思路
if(n == 1)
{
tmp = head->next;
return head;
}
ListNode* new_head = reverse(head->next,n-1); //子问题,位置要减1
head->next->next = head; //反转
head->next = tmp; //拼接尾部
return new_head;
}
};复杂度分析
时间复杂度:一层循环,时间复杂度为O(N)
空间复杂度:其最坏递归空间复杂度为O(N).

京公网安备 11010502036488号