[程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序

题目描述

给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点。

题解

内部函数reverse实现链表beg到end的翻转,以及与l和r的连接。
外部函数reverseKNodes实现区间的移动(即四个实参的更新),以及整个链表头节点的赋值。
时间复杂度O(n),额外空间复杂度O(1)

代码


public class Main {
	public static void main(String args[]) {
		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=n1;
		int k=2;
		Node newHead=reverseKNodes(head,k);
		Node p=newHead;
		while(p.next!=null) {
			System.out.println(p.val);
			p=p.next;
		}
	}
	
	public static Node reverseKNodes(Node head,int k) {
		if(k<2) {
			return head;
		}
		
		boolean firstKNodesTag=true;//是否是第一个小组
		Node newHead=null;//新链表表头
		
		Node l=null;//前一个小组的尾节点
		Node beg=null;//小组开始节点
		Node cur=head;//当前
		Node next=null;//当前下一个节点
		
		int cnt=1;
			
		while(cur!=null) {	
			next=cur.next;
			if(cnt==k) {
				if(firstKNodesTag) {//新链表表头
					newHead=cur;
					beg=head;
					firstKNodesTag=false;
				}
				
				reverse(l,beg,cur,next);
				beg=next;//
				l=beg;
				cnt=0;
			}
			cur=next;
			++cnt;
		}
		return newHead;
	}
	
	public static void reverse(Node l,Node beg,Node end,Node r) {
		Node pre=beg;//
		Node cur=beg.next;//
		Node next=null;
		while(cur!=r) {
			next=cur.next;
			cur.next=pre;
			pre=cur;
			cur=cur.next;
		}
		if(l!=null) {
			l.next=end;
		}
		beg.next=r;//
	}
}

posted on 2019-05-19 23:25  coding_gaga  阅读(152)  评论(0编辑  收藏  举报

导航