题目:给定一个单向链表的头节点head,以及两个证书 from和 to,在单链表上把第 from 个节点到第 to 个节点这一部分进行反转。
例如:
1——>2——>3——>4——>5——>null ,from = 2,to=4
调整结果为:
1——>4——>3——>2——>5——>null
要求:
(1)如果链表长度为N,时间复杂度要求O(N),额外空间复杂度要求为O(1)。
(2)如果不满足 1<=from<=to<=N,则不用调整
思路:
(1)先遍历链表,找出链表的长度 len,和 要反转部分的前一个节点pre和后一个节点 pos
(2)然后 让cur指针指向要反转部分的第一个节点,将这个节点的next指针直接指向 pos。
然后开始反转要反转的部分 ,也就是 from到to的部分。
(3)反转完之后,如果fre节点不为空,就将fre的next指针指向 cur,也就是指向反转后反转部分的最后一个节点。然后返回head。
(4)如果fre为空,直接返回反转后反转部分的最后一个节点,此时他就是头节点。
代码实现:
//反转部分单链表
public static Node reversePart(Node head,int from ,int to) {
//获取链表长度 len
int len = 0;
Node cur = head;
Node pre = null;
Node pos = null;
while (cur != null) {
len++;
//找要反转部分的前一个节点和后一个节点
pre = len == from - 1 ? cur : pre;
pos = len == to + 1 ? cur : pos;
cur = cur.next;
}
//len为链表长度
if (from > to || from < 1 || to > len) {
return head;
}
//这里cur是要反转的第一个节点
cur = pre == null ? head : pre.next;
Node cur1 = cur.next;
cur.next = pos; //将反转的第一个节点和 pos连上
Node next = null;
//在这个里面先反转 要反转的部分
while (cur1 != pos) {
next = cur1.next;
cur1.next = cur; //将后一个指针指向他前面节点
cur = cur1;
cur1 = next;
}
//现在反转部分已经连完 将反转部分与未反转部分相连
if (pre != null) {
pre.next = cur;
return head;
}
return cur;
}