定义
- 反转链表即将整个链表倒转过来,如1->2->3->NULL反转为NULL<-1<-2<-3
- 遍历整个链表时,将当前节点的next改为指向前一个元素,由于节点没有引用它前一个元素,所以要提起存储前一个节点。因为是从前向后遍历,更改完前一个元素之后缓存前一个元素,接下来遍历当前元素时就可以指向前一个元素,再缓存当前元素,接着遍历下去
- 当遍历到NULL时,该元素的前一个元素就是反转链表的表头,而它前一个元素被缓存了
例题
1、反转链表
题目地址为Leetcode 206
1.1 解题思路
- 本题就是基础的反转链表
1.2 程序代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre=null,cur=head,temp=null;
while(cur!=null){
temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return pre;
}
}
2、K 个一组翻转链表
题目地址为Leetcode 25
2.1 解题思路
- 学过反转链表后,我们可以把反转链表的方法单独拿出来
- 每次反转一个组,反转完成后认为后面的不够分组,拼接回去
- 当下一次循环真的不够分组的时候可以直接返回
- 当下一次循环够分组,再修改上一组指向这一组的指针
- 假设目前的分组不是第一个分组,它反转后,需要被前一个分组的尾指针连接,还需要将当前分组的尾指针指向未分组链表的头部,为便于第一个分组统一处理,可以创建一个表头,这样也方便返回整个串
- 结束条件为
- 整个链表正好可以分成K长度的分组,这样最后的head应该为空
- 如果不可以正好分,则最后剩下的一定不够分组,此时按照长度遍历长度不足时tail就已经为空
2.2 程序代码
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode start=new ListNode(0);
start.next=head;
ListNode pretail=start,tail=null;
while(head!=null){
tail=pretail;
for(int i=0;i<k;i++){
tail=tail.next;
if(tail==null)
return start.next;
}
ListNode nextgroup=tail.next;
ListNode[] listnodes=reverse(head,tail);
head=listnodes[0];
tail=listnodes[1];
pretail.next=head;
tail.next=nextgroup;
head=nextgroup;
pretail=tail;
}
return start.next;
}
public ListNode[] reverse(ListNode head,ListNode tail){
ListNode pre=null,cur=head,temp=null;
while(pre!=tail){
temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return new ListNode[]{tail,head};
}
}