题目描述:
给定一个单向链表的头结点head,以及两个整数from和to,在单向链表上把第from个节点到第to个节点这一部分进行反转
例如:1->2->3->4->5->null, from = 2, to = 4
调整结果为:1->4->3->2->5->null
再如:
1->2->3->null, from = 1, to = 3
调整结果为:
3->2->1->null
要求:
1.如果链表的长度为N,时间复杂度要求O(n),额外空间复杂度要求为O(1)
2.如果不满足1 <= from <= to <=N,则不用调整
思路:注意反转的顺序,比如上述的第一个例子中,先把2和4的下一节点5连接,然后再依次把3和2连接,把4和3连接,对于第二个例子,同样,先把1和3的下一个节点null连接,然后依次把2和1连接,把3和2连接,这是两个例子的共同特点,有所不同的是,第一点:第一个例子还需要将1和已经反转好的链表进行连接 ;第二点:两者返回的头结点不同,对于第一个例子来说直接返回头结点head就OK,对于第二个例子来说需要返回是3这个节点
public class Code_012_ReversePart {
public static class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
}
}
public static Node reversePart(Node head, int from, int to) {
int count = 0;
Node toNext = null; //代表to位置节点的后一个节点
Node fromPrev = null; //代表from位置节点的前一个节点
Node cur = head;
while(cur != null) {
count++;
fromPrev = count == from - 1 ? cur : fromPrev;
toNext = count == to + 1 ? cur : toNext ;
cur = cur.next;
}
if (from > to || from < 1 || to > count) {
return head;
}
cur = fromPrev == null ? head : fromPrev.next;
Node prev = toNext;
Node next = null;
while(cur != toNext) {
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
//头结点不用反转的情况,将不用反转的链表和已经反转好的链表进行连接
if (fromPrev != null) {
fromPrev.next = prev;
return head;
}
//头结点需要反转的情况,返回新的头结点
return prev; //
}
}