问题描述
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.
Example:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Note:
Only constant extra memory is allowed.
You may not alter the values in the list’s nodes, only nodes itself may be changed.
题目要求: 输入一个链表和一个数字k,将链表的每k个节点倒序排列然后输出链表
解题思路
直接做,因为这题感觉有点容易乱就分成了三个函数来做。每次得到prev和next的位置,然后把中间的k个元素给颠倒了,函数输出颠倒后的头和尾节点然后把prev和next给接上。
代码实现
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode prev = dummy, next = null;
//checkPElements函数用来判断是否存在k个可用的元素,返回最后一个元素
while((next = checkPElements(prev, k)) != null) {
next = next.next; //这里的next元素是最后一个元素后面的元素,即等会要接回来的位置
//reverseElements函数用来把中间的元素给颠倒顺序,然后输出头尾元素数组。
ListNode[] result = reverseElements(prev.next, k);
//头接到前面元素后
prev.next = result[0];
//尾接到后续元素前面
result[1].next = next;
//prev设置成k个元素的尾
prev = result[1];
}
return dummy.next;
}
public ListNode checkPElements(ListNode head, int k) {
ListNode p = head;
for(int i = 0; i < k; i++) {
if(p == null) return null;
else p = p.next;
}
return p;
}
public ListNode[] reverseElements(ListNode head, int k) {
ListNode prev = null, next, p = head;
for(int i = 0; i < k; i++) {
next = p.next;
p.next = prev;
prev = p;
p = next;
}
return new ListNode[]{prev, head};
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(1)(没有创建节点,直接改变链表的指向)
分析
对于链表问题,最好可以找张纸找个笔自己写写画画,不然自己空想比较容易出问题。