开始想着化简问题,Reverse其实就是首尾两个元素互换位置,然后循环调用即可,但是由于链表互换位置后面元素的前一个元素难以得到(单向链表)。所以并不好用,下面是写了一半的代码。
public class ReverseNodesInKGroup25 { public ListNode reverseKGroup(ListNode head, int k) { ListNode dummy = new ListNode(-1); dummy.next = head; ListNode p = dummy; boolean isEnough = true; for(int i=0;i<k;i++) { if(p.next!=null) p=p.next; else {isEnough=false;break;} } ListNode pl,pr; while(isEnough) { for(int i=0;i<k/2;i++) { for(int j=0;j<=i;j++) { pl } } } } private void Swap2Nodes(ListNode pl,ListNode pr) { ListNode templ=pl.next.next,tempr=pr.next.next; pl.next.next = tempr;pr.next.next = templ; templ=pl.next;tempr=pr.next; pl.next = tempr;pr.next = templ; } }
然后查看discuss大神做法,递归,觉得写得很好,尤其是将单线链表Reverse这个过程提炼的很到位。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseKGroup(ListNode head, int k) { ListNode tail = head; //link head to tail int count =0; while(tail!=null&&count!=k) { //tail is first at the k+1st node tail = tail.next; count++; } if(count==k) { tail = reverseKGroup(tail,k); while(count-->0) { ListNode temp = head.next; head.next = tail; tail = head; head = temp; } head = tail; } return head; } }
5ms,44.94%
看了下最快的3ms循环答案,不是很简洁,自己结合上面递归改一下:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseKGroup(ListNode head, int k) { if(k==1) return head; ListNode dummy = new ListNode(-1),cur=head,tail=head; ListNode lastTail = dummy; //link the last node of the ahead loop to the new head of the next loop dummy.next = head; while(cur!=null) { for(int i=0;i<k;i++) { //find the tail node(next head) in this loop if(tail==null) return dummy.next; tail = tail.next; } ListNode nextHead = tail; //store tail of this loop and next head for the next loop while(cur!=nextHead) { ListNode temp = cur.next; cur.next = tail; tail=cur;cur=temp; } lastTail.next=tail;lastTail=head;head=nextHead;cur=nextHead;tail=nextHead; } return dummy.next; } }
自己改了之后发现确实需要很多ListNode,于是优化了命名方式。4ms,可以了。
递归和循环两种方法都要会。