接上一章,依旧是翻转问题
我们希望给你一组链表
1,2,3,4,5
然后让你翻转
2,1,4,3,5
...
这也是一个算法问题,那么对于这种算法至少需要三个指针
cache:存放第三个节点
begin:当前链对的第一个节点
end:当前链队的第二个节点
基本思想很简单:
public static ListNode reverse(ListNode head){
ListNode cache;
ListNode begin = head;
ListNode end = head.next;
ListNode reNode = null;
if(end == null){
reNode = begin;
}else {
reNode = end;
}
while (end != null&&end.next!= null){
//捉对翻转
cache = end.next;
end.next = begin;
begin.next = cache;
//跳到下一对
begin = cache;
end = cache.next;
}
return reNode;
}
but...
很明显,这样的逻辑还存在一个很严重的漏洞
当这个链表只存在两个时,是成立的,
但是每当存在四个时,我们将两个作为一对,那么,当我们对第二对发生交换时,第二对的end变成了begin,然而!!来自第一对的末位元素指向的却是已经变成了“end”的begin!!
所以,翻转一定会出错!
那么解决办法就非常简单了,我们需要引入第四个指针pairTail,用来指向交换之后的“begin”的end
public static ListNode reverse(ListNode head){
ListNode cache;
ListNode begin = head;
ListNode end = head.next;
ListNode pairTail = null;
ListNode reNode = null;
if(end == null){
reNode = begin;
}else {
reNode = end;
}
while (end != null&&end.next!= null){
//捉对翻转
cache = end.next;
end.next = begin;
begin.next = cache;
//上一对的对尾巴指向下一对的对首,也就是end 其实等于"begin"
if(pairTail!= null){
pairTail.next = end;
}
pairTail = begin;
//跳到下一对
begin = cache;
end = cache.next;
}
return reNode;
}