问题描述:1->2->3->4,假设k=2进行反转,得到2->1->4->3;k=3进行反转,得到3->2->1->4
算法思想:基本操作就是链表反转,将k个元素当作滑动窗口,依次进行反转。
1 public class ReverseNodesInKGroup { 2 public ListNode reverseKGroup(ListNode head, int k) { 3 if (k == 1 || head == null || head.next == null) 4 return head; 5 ListNode first = head, last = head; 6 ListNode preHead = new ListNode(-1); 7 preHead.next = head; 8 ListNode preGroup = preHead, nextGroup = preHead; 9 int count = 1; 10 while (last != null) 11 { 12 if (count != k) 13 { 14 last = last.next; 15 count++; 16 } 17 else 18 { 19 nextGroup = last.next; 20 reverseList(first, last);// 节点反转后,first <- ... <-clast 21 preGroup.next = last;// 前面转换过的组连接到新的组,pregrou记录prehead,最后返回prehead 22 preGroup = first; 23 first.next = nextGroup; 24 first = nextGroup; 25 last = nextGroup; 26 count = 1; 27 } 28 29 } 30 return preHead.next; 31 } 32 //基本反转操作 33 private void reverseList(ListNode head, ListNode tail) { 34 ListNode pre = new ListNode(-1), node = head; 35 pre.next = head; 36 while (pre != tail) { 37 ListNode temp = node.next; 38 node.next = pre; 39 pre = node; 40 node = temp; 41 } 42 } 43 }
特例Swap nodes in pairs
问题描述:给一序列,交换每相邻的两个元素,并返回头结点。例如:1-2-3-4 返回序列2-1-4-3
算法思路:除了第一组元素,其他每次交换一对儿元素,要改变四个指针。所以,定义四个指针。其中只有两个指针是不想关,其他依赖这两个指针。
方法一:
1 public ListNode swapPairs(ListNode head) { 2 if(head == null || head.next == null) 3 { 4 return head; 5 } 6 ListNode pPre = new ListNode(0); 7 pPre.next = head; 8 ListNode p1 = head; 9 ListNode p2 = null; 10 ListNode pNext = null; 11 ListNode temp = null; 12 while(p1!= null && p1.next != null) 13 { 14 p2 = p1.next; 15 if(p1 == head) 16 { 17 temp = p2; 18 } 19 pNext = p2.next; 20 p2.next = p1; 21 p1.next = pNext; 22 pPre.next = p2; 23 pPre = p1; 24 p1 = pNext; 25 } 26 return temp; 27 28 }
方法二:
public static ListNode swapPairs(ListNode head) { ListNode pPrepre = null; //节点对的前前元素 ListNode pPre = null; //节点对的前一个元素,依赖p ListNode p = head; //要移动的节点对的第一个元素 ListNode pNext = null; //节点对的第二个元素,依赖p while (p != null && p.next != null) { pPre = p; p = p.next; pNext = p.next; if (pPre == head) { head = p; } if (pPrepre != null) { pPrepre.next = p; } p.next = pPre; pPre.next = pNext; pPrepre = pPre;//其他元素都依赖p,但pPrepre不依赖p,所以每次移动pPrepre和p p = pNext; } return head; }