以k个元素为一组反转单向链表

问题:

以k个元素为一组,反转单向链表。比如:

输入: 1->2->3->4->5->6->7->8->null and k = 3

输出:3->2->1->6->5->4->8->7->null. 

分析:

我们可以把整个链表分成多个长度为 k  的子链表, 然后,我们再反转每一个子链表(递归)。问题的关键是我们需要把每个子链表再连接起来。所以,对每一个子链表操作以后,我们需要返回该子链表的头(head),然后,我们设置前一个子链表的最后一个node,把它的next 设置成下一个链表返回的头(head),这样,所有的子链表就连接起来了。

public static Node reverse (Node head, int k) {
	Node current = head;
	Node next = null;
	Node prev = null;
    int count = 0;   
    
    /*reverse first k nodes of the linked list */
    while (current != null && count < k) {
       next  = current.next;
       current.next = prev;
       prev = current;
       current = next;
       count++;
    }
 
    /* next is now a pointer to (k+1)th node
       Recursively call for the list starting from current.
       And make rest of the list as next of first node */
    if(next !=  null) {
    	head.next = reverse(next, k); 
    }
 
    /* prev is new head of the input list */
    return prev;
}

这个问题也可以使用非递归的方法,基本上问题的处理方式和递归是一样的,但是,非递归的方式要稍微复杂一点,因为每次对子链表反转以后,我们需要更新前一个子链表最后一个node 的next 值。代码如下:

class Node {
     int val;
     Node next;
     Node(int x) {
         val = x;
         next = null;
     }
}

public class Solution {
	
	public static void main(String[] args) {
		Solution s = new Solution();
		
		Node n1 = new Node(1);
		Node n2 = new Node(2);
		Node n3 = new Node(3);
		Node n4 = new Node(4);
		Node n5 = new Node(5);
		
		n1.next = n2;
		n2.next = n3;
		n3.next = n4;
		n4.next = n5;
		
		Node head = s.ReverseInGroups(n1, 2);
		while (head != null) {
			System.out.println(head.val);
			head = head.next;
		}
	}
	public Node ReverseInGroups(Node current, int k) {
		if (current == null || current.next == null ) return current;
		//store the new head of the list
		Node newHead = null;
		
		//store the last node in the sub-list, 
		//we will update its next value when finishing
		//reversing the next sub-list
		Node previousGroupTail = null;
		int count = 1; //used to track the first sub-list
	    while (current != null) {	
	    	// the actual tail in the sub-list
	    	Node groupTail = current;
	    	//reverse
	    	Node prev = null;
	    	Node next = null;
	    	for (int i = 1; i <= k && current != null; i++) {
	            next = current.next;
	            current.next = prev;
	            prev = current;
	            current = next;
	        }
	        // get the new head of the whole list
	    	if (count == 1) {
	    		newHead = prev;
	    		count++;
	    	}
	    	// update the next value of the last node in
	    	// each sub-list
	    	if (previousGroupTail != null) {
	    		previousGroupTail.next = prev;
	    	}
	    	previousGroupTail = groupTail;
	    }
	    return newHead;
	}
}

参考:http://www.geeksforgeeks.org/archives/8014

转载请注明出处:http://blog.csdn.net/beiyetengqing





  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值