Algorithm之路二十五:Reverse Nodes in k-Group

题目:(还是看原题比较清楚)

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked 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.

举例:

1->2->3->4->5->6,2      --->      2->1->4->3->6->5

1->2->3->4->5->6,3      --->      3->2->1->6->5->4

1->2->3->4->5->6,6      --->      6->5->4->3->2->1

1->2->3->4->5->6,4      --->      4->3->2->1->5->6

1->2->3->4->5->6,5      --->      5->4->3->2->1->6

1->2->3->4->5->6,7      --->      6->5->4->3->2->1

思路:

在Swap Nodes in Pairs一题中,利用递归可以完成,那么在此题中也可以利用递归的思想,在每层递归中,只需要将链表的前k个节点逆置,逆置的方法是设置一个指针指向逆置链的头部,插入时,从头部插入。

但是我并没有利用递归,我是利用递归的方法,整体思路可以很清晰,但是在逆置的时候,可能思路会乱一点。

代码:

public class Reverse_Nodes_in_k_Group {

	public static class ListNode
	{
		int val;
		ListNode next;
		ListNode(int x) { val = x;}
	}
	public static ListNode reverseKGroup(ListNode head, int k)
	{
		if(k == 0 || k == 1)return head;
		if(head == null)return null;
		ListNode temp = head,current_next = null,finished_end = head,reversing_start = head,reversing_end = head;
		int count1 = 0;
		while(temp != null)
		{
			count1++;
			temp = temp.next;
		}
		if(count1 < k)return head;
		int count = 2;
		temp = head.next;
		while(temp != null)
		{
			current_next = temp.next;
			if(count%k == 1)
			{
				reversing_start = temp;
				reversing_end = temp;
				if(count1 - count < k - 1)break;
			}
			else
			{
				temp.next = reversing_start;
				reversing_start = temp;
				if(count%k == 0)
				{
					finished_end.next = reversing_start;
					finished_end = reversing_end;
				}
			}
			if(count == k) head = temp;
			temp = current_next;
			count++;
		}
		finished_end.next = reversing_start;
		reversing_end.next = current_next;
		return head;
    }
	public static void main(String[] args)
	{
		ListNode head = new ListNode(1);
		head.next = new ListNode(2);
		head.next.next = new ListNode(3);
		head.next.next.next = new ListNode(4);
		head.next.next.next.next = new ListNode(5);
		head.next.next.next.next.next = new ListNode(6);
		head.next.next.next.next.next.next = new ListNode(7);
		head.next.next.next.next.next.next.next = new ListNode(8);
		head.next.next.next.next.next.next.next.next = new ListNode(9);
		ListNode temp = reverseKGroup(head,2);
		while(temp != null)
		{
			System.out.println(temp.val);
			temp = temp.next;
		}
	}
}

时间复杂度:

将链表按k分成一个一个的子链,在遍历链表的时候,如果当前节点不是一个子链的头部,那么需要做的操作有两步,但是如果是子链的的尾部时,需要做四步操作,如果是子链的头部,需要做两步操作,设链表的长度为n,则总的不是为n/k*4+n/k*2+(n-n/k)*2=2n+n/k*2,所以时间复杂度为O(2n+n/k*2)。

空间复杂度:

O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值