题解 | #链表中的节点每k个一组翻转#
链表中的节点每k个一组翻转
https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e
方法1、两个堆
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * } */ public class Solution { /** * * @param head ListNode类 * @param k int整型 * @return ListNode类 */ public ListNode reverseKGroup (ListNode head, int k) { // write code here //思路:一个栈即可,每次k个元素入栈,如果不够k说明已经到了最后一部分 if(head==null)return null; if(k==1)return head; Stack<ListNode>stack=new Stack<>(); Stack<ListNode>stack2=new Stack<>(); int i=1; ListNode cur=head,pre=null; ListNode partTail=null;//记录每一部分的最后一个元素 //循环结束的标志,cur==null while(cur!=null){ stack.push(cur); cur=cur.next; //第一部分,简单翻转 if(i==k){ ListNode cur1=stack.pop(); head=cur1; //出栈 while(!stack.isEmpty()){ cur1.next=stack.pop(); cur1=cur1.next; } //记录本部分最后一个元素 partTail=cur1; }else if(i%k==0){ //栈中元素数已经到了k个 //出栈,连接构造反向链表 ListNode cur1=stack.pop(); //此时该部分的首元素为cur1 //将上一部分的尾元素连接到cur1 partTail.next=cur1; //循环出栈 while(!stack.isEmpty()){ cur1.next=stack.pop(); cur1=cur1.next; } //记录本部分最后一个元素 partTail=cur1; } i++; } //while循环中i多加了一个1,需要结束后减去他 i--; //如果k比链表长,则整个链表都属于最后一部分不用翻转 if(k>i)return head; //如果k=i,说明只有第一部分,只需要将末尾元素next填null即可 if(k==i){ partTail.next=null; return head; } //只有i不能被k整除时才有最后一部分 if(i%k!=0){ //如果栈中有元素,说明k不能被链表长度整除,还残留最后一部分链表 //这一部分不翻转 while(!stack.isEmpty()){ cur=stack.pop(); stack2.push(cur); } partTail.next=cur; while(!stack2.isEmpty()){ cur.next=stack2.pop(); cur=cur.next; } cur.next=null; } return head; } }方法2、递归(参考别人的)
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * } */ public class Solution { /** * * @param head ListNode类 * @param k int整型 * @return ListNode类 */ public ListNode reverseKGroup (ListNode head, int k) { // write code here //思路:递归 //终止条件:访问到null元素,此时有若干情况: //1、k>length,说明只有最后一部分,不用变,直接return head //2、k==length,说明只有第一部分,翻转返回即可 //3、k<length,说明有多部分,递归 ListNode partTail=null;//每一部分的尾就是原链表的头 ListNode cur=head; for(int i=1;i<=k;i++){ //如果在i在到k的过程中就访问到了null元素 //说明k>length,符合情况1 if(cur==null) return head; cur=cur.next; } partTail=cur; //翻转需要记录pre和next节点 ListNode pre=null,next; cur=head; while(cur!=partTail){ next=cur.next; cur.next=pre; pre=cur; cur=next; } //当前尾指向下一段要翻转的链表 head.next=reverseKGroup(partTail,k); return pre; } }