题目:(还是看原题比较清楚)
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)。