https://oj.leetcode.com/problems/reverse-nodes-in-k-group/
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
解题思路:
这题需要解读一下。题意就是每k个节点转置一下,然后下k个节点再转置一下,如果k大于剩下的元素了,那么剩下的元素不动。最后返回这个链表。
这样一解读,思路就清楚了。我们首先需要实现一个已知首尾节点的链表的转置的方法,这样的方法里我们需要时刻保存三个指针,分别指向当前节点、以及当前节点的前驱和后驱节点。
有了这个方法后,我们可以在这个链表中,每k个元素,用一下这个方法,将这段链表转置。但是,一定不要忘记,把前面的尾节点的next指向当前转置链表的首节点,否则就断了。循环终止的条件是head != null,这时代表正好n为k的倍数,head到最后null的地方,循环就要终止。
内部循环中,遇到剩下不足k个元素就返回。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode reverseKGroup(ListNode head, int k) { if(head == null){ return null; } ListNode returnNode = head; ListNode pre = new ListNode(0); int times = 0; while(head != null){ ListNode tail = head; for(int i = 0; i < k - 1; i++){ if(tail.next == null){ return returnNode; } tail = tail.next; } //这个很重要,必须把转置后的头节点接在前面已转置的链表的后面! pre.next = reverseList(head, tail); //第一次转置的时候取得待返回的头节点 if(times == 0){ returnNode = tail; } pre = head; head = head.next; times++; } return returnNode; } public ListNode reverseList(ListNode head, ListNode tail){ ListNode pre = new ListNode(0); pre.next = head; ListNode next = head.next; ListNode tailNext = tail.next; ListNode traverse = head; while(traverse != tailNext){ next = traverse.next; traverse.next = pre; pre = traverse; traverse = next; if(next != null){ next = next.next; } } head.next = tailNext; return tail; } }
// 20180801
/** * 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 dummy = new ListNode(0); dummy.next = head; ListNode cur = dummy; while (cur != null) { ListNode curnext = cur.next; cur.next = reverseK(cur.next, k); // 这时curnext已经是K个节点中的最后一个节点,直接将cur移到这个位置开始下一次倒置 cur = curnext; } return dummy.next; } public ListNode reverseK(ListNode head, int k) { if (head == null || head.next == null || k == 1) { return head; } ListNode dummy = new ListNode(0); dummy.next = head; ListNode cur = dummy; // 不足k个node直接返回 for (int i = 0; i < k; i++) { cur = cur.next; if (cur == null) { return dummy.next; } } cur = head; for (int i = 1; i < k; i++) { ListNode curnext = cur.next; cur.next = cur.next.next; curnext.next = dummy.next; dummy.next = curnext; } return dummy.next; } }