链表----将单链表的每K个节点之间逆序

链表----将单链表的每K个节点之间逆序_第1张图片

关键点:

一、使用栈

  1. 从左到右遍历链表,如果栈的大小不等于K,就将节点不断压入栈;
  2. 当栈的大小第一次达到K时,说明凑齐了K个节点进行逆序,从栈中依次弹出这些节点,并根据弹出的顺序进行重连,同时记录新的头部,该组的最后一个节点连接下一个节点;
  3. 当栈的大小每次到达K时,说明又凑齐了一组,从栈中弹出并进行重连后,该组的最后一个节点连接下一个节点,更新pre,然后继续凑下一组,直到链表被遍历完;
  4. 最后返回新的头节点

二、仅使用指针 

用变量记录每一组开始的第一个节点和最后一个节点,然后直接逆序调整,方法思想同上。

//一、利用栈
	public static Node reverseKNodes1(Node head,int k) {
		if(head == null || head.next == null || k < 2) return head;
		Stack s = new Stack();
		Node newHead = head;
		Node cur = head;
		Node next = null;//记录压入k个元素后的第 k+1 个元素
		Node pre = null;//记录k个元素的前一个元素
		while(cur != null) {
			next = cur.next;
			s.push(cur);
			if(s.size() == k) {	
				//逆序并返回栈底元素
				pre = resign1(s,pre,next);
				newHead = newHead == head ? cur : newHead;
			}	
			cur = next;	
		}
		return newHead;	
	}
	
	public static Node resign1(Stack s, Node left,Node right) {
		Node cur = s.pop();
		if(left != null) {
			left.next = cur;
		}
		while(!s.isEmpty()) {
			cur.next = s.pop();
			cur = cur.next;
		}
		cur.next = right;
		return cur;
	}
	//二、仅使用指针 
	public static Node reverseKNodes2(Node head,int k) {
		if(head == null || head.next == null || k < 2) return head;
		int count = 0;
		Node cur = head;
		Node next = null;//记录k个元素的后一 个元素
		Node pre = null;//记录k个元素的前一个元素
		Node start = null;//k个元素的首元素
		
		while(cur != null) {
			next = cur.next;
			count++;
			
			if(count == k) {
				start = pre == null ? head : pre.next;
				head = pre == null ? cur : head;
			    resign2(pre,start,cur,next);
			    pre = start;
			    count =0;
			}
	
			cur = next;	
		}
		return head;	
	}
	//start和end之间逆序
	public static void resign2(Node left,Node start,Node end,Node right) {
		Node pre = start;
		Node cur = start.next;
		Node next = null;
		while(cur != right) {
			next = cur.next;
			cur.next = pre;
			pre = cur;
			cur = next;
		}
		
		if(left != null) {
			left.next = end;
		}
		start.next = right;
		
	}

 

你可能感兴趣的:(程序员代码面试指南)