题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
大体思路
这里提供两种做法,第一种使用栈,每次循环放入k个节点,然后依次出栈连接实现翻转,但要注意前驱节点的连接问题,在代码中有注释,以下代码也只是第一种的写法。
第二种也是每次遍历k个节点,但不使用栈了。保存k个节点的前驱节点和k个节点中的最后一个尾节点,然后将前驱节点的next依此连入尾节点,同样,要注意链表长度是否是k倍数的问题。
代码
public class problem25 {
//Definition for singly-linked list.
public static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode reverseKGroup(ListNode head, int k) {
if(k==1) return head;//特判
Stack<ListNode> st=new Stack<ListNode>();
ListNode pre=new ListNode(0);//额外的头节点,用于连接翻转
ListNode re=pre;//保存结果
int i=0;
while(head!=null){
i=0;
//前驱节点连接
pre.next=head;
//依此将k个节点入栈
for(i=0;i<k&&head!=null;i++){
st.add(head);
head=head.next;
}
if(i!=k) break;
//依此出栈,并连接节点,实现翻转
while(st.size()!=0){
pre.next=st.pop();
pre=pre.next;
}
}
//判断上述循环退出的情况,如果链表长度是k的倍数,那么最后一个节点还指向倒数第二个,会形成死循环
if(i==k) pre.next=null;
return re.next;
}
public static void main(String[] args) {
ListNode a=new ListNode(1);
a.next=new ListNode(2);
a.next.next=new ListNode(3);
a.next.next.next=new ListNode(4);
a.next.next.next.next=new ListNode(5);
problem25 pro=new problem25();
ListNode re=pro.reverseKGroup(a, 2);
while(re!=null){
System.out.println(re.val);
re=re.next;
}
}
}
2
1
4
3
5