LeetCode 25 Reverse Nodes in k-Group K个一组反转节点

题目

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为2时候,2个一组反转。

思路

和上一道题思路不一样。因为K不确定,不能像交换2个节点似的,直接标记好下一个节点是什么在交换。

为此想到的办法是反转链表。即给定一个链表,把他所有节点反转过来。

接着只需要将原来题目给的链表按K分组。然后把每组都反转过来。并返回翻转后的最后一个节点。

代码

  public static ListNode reverseKGroup(ListNode head, int k) {
		 if(head == null)
			 return null;
	     ListNode root = new ListNode(0);
	     root.next = head;
	     ListNode pre = root;
	     int count = 0;
	     ListNode temp = null;
	     while(head != null)
	     {
	    	 count++;//计数
	    	 if(count ==  k)//到K处理
	    	 {
	    		 temp= head.next;//@ 1
	    		 pre = reverse(pre,head.next);//pre为链表前一个,head.next为后一个。即把这个区间的链表反转
	    		 count = 0;
	    		 head = temp;//@ 2
	    	 }
	    	 else 
	    		 head = head.next;//@ 3
	     }	   		 
		 return root.next;
	    }
	 public static ListNode reverse(ListNode pre,ListNode end)
	 {
		 ListNode last = pre.next;
		 ListNode cur = last.next;
		 while(cur!=end)
		 {
			 last.next = cur.next;
			 cur.next = pre.next;
			 pre.next = cur;
			 cur = last.next;
		 }		 
		 return last;
	 }
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		ListNode a = new ListNode(1);
		ListNode b = new ListNode(2);
		ListNode c = new ListNode(3);
		ListNode d = new ListNode(4);
		a.next = b;
		b.next = c;
		c.next = d;
		d.next = null;
		ListNode p =reverseKGroup(a,2);
		while(p!=null)
		{
			System.out.print(p.val+"\t");
			p = p.next;
		}
	}

在@1 和@2 的地方 和@3的目的是一样的。即把指针指向下一个节点。

之所以不同是因为。@1和@2是在反转后的。加入链表为1234.K为2,此时head指向2,但是反转过后,head.next指向为1 而不是3.所以在反转处理之前应该保存head.next的位置信息。在处理结束后,把head指向保存结果。


这道题的核心在于反转链表。

贴一个反转链表的核心代码,仅供参考。

public class ReverseList {

	public static ListNode reverse( ListNode a)
	{
		ListNode root = new ListNode(0);
		root.next = a;
		ListNode cur = a.next;
		while(cur!=null)
		{
			a.next = cur.next;   //假设为1234 此时a指向1,cur指向2,首先使得1的下一个为3,接着
			cur.next = root.next;//2的下一个为1,root的下一个为2 ,cur指向3。此时为2134
			root.next = cur;	//当cur为3时,首先让1指向4,3指向2 root指向3 得到3214;同理
			cur =a.next;
		}		
		return root.next;				
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		ListNode a = new ListNode(1);
		ListNode b = new ListNode(2);
		ListNode c = new ListNode(3);
		ListNode d = new ListNode(4);
		a.next = b;
		b.next = c;
		c.next = d;
		d.next = null;
		ListNode p =reverse(a);
		while(p!=null)
		{
			System.out.print(p.val+"\t");
			p = p.next;
		}

	}

}



点赞