给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例:输入1->2->3->4->5,k = 2。返回2->1->4->3->5
输入1->2->3->4->5,k = 3。返回3->2->1->4->5
思路:一个先行指针r,先往前走k个节点,如果r走不到k个节点就空了,则直接返回。如果可以走k个节点,则对r前的这k个节点进行翻转,可以使用栈进行操作。翻转后接着再继续让r前行k个节点,如此往复。
我的代码:
public class ReverseNodesInKGroup {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode r = head,pre = head,p;
ListNode q = r; //q为要调整的最后一个节点
int i = 0;
while (i<k&&r!=null) {
q = r;
r = r.next;
i++;
}
if(r == null && i<k) return head;
Stack<ListNode> stack = new Stack<>();
while (!pre.equals(q)) {
stack.push(pre);
pre = pre.next;
}
stack.push(pre);
head = stack.pop();
pre = head;
while (!stack.isEmpty()) {
pre.next = stack.pop();
pre = pre.next;
}
//pre为调整完了的链表的最后一个节点,也是下个调整好的表要连接的地方
pre.next = null;
while (r!=null) {
i = 0;
p = r;
while (i<k&&r!=null) {
q = r;
r = r.next;
i++;
}
if(r == null && i!=k) {
pre.next = p;
return head;
}
while (!p.equals(q)) {
stack.push(p);
p = p.next;
}
stack.push(p);
while (!stack.isEmpty()) {
pre.next = stack.pop();
pre = pre.next;
}
pre.next = null; //一定要设为空
}
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);
ListNode t = new ReverseNodesInKGroup().reverseKGroup(head, 2);
while (t!=null) {
System.out.print(t.val+" ");
t = t.next;
}
}
}
除了这种方法以外,也可以用递归方法(上面的思路描述很容易想到递归)。