[链表]7.链表中的节点每k个一组翻转[京东,快手,CVTE]

将给出的链表中的节点每k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度O(1)

例如:

给定的链表是1->2->3->4->5

对于 k=2, 你应该返回 2->1->4->3->5

对于 k=3, 你应该返回 3->2->1->4->5

解答:利用栈结构的解法

1.如果k的值小于2,不用进行任何调整,因为k<1没有意义,k=1,代表一个节点为1组进行逆序,原链表没有进行任何变化。

2.从左到右遍历链表,如果栈的大小不等于看,就将节点不断压入栈中

3.当栈的大小第一次到达k时,说明第一次凑齐了k个节点进行逆序,从栈中依次弹出这些节点,并根据弹出的顺序重新连接,这一组逆序完成后,需要记录一下新的头部,同时第一组的最后一个节点(原来是头节点)应该连接下一个节点

例如:链表1->2-->3->4->5->6->7->8->null,k=3.第一组节点进入栈,从栈顶到栈底依次为3,2,1.逆序重连为3->2->1->......,然后节点1去连接节点4,链表变为3->2->1->4->5-->6->7-->8->null,之后从节点4不断处理k个节点为一组的后续情况,也就是步骤4,并且需要记录节点3,因为链表的头部已经改变,整个过程结束后需要返回这个新的头节点,记为newHead.

4.步骤3之后,当栈的大小每次到达k时,说明又凑齐了一组应该进行逆序的节点,从栈中依次弹出这些节点,并根据弹出的顺序重新连接。这一组逆序完成之后,该组的第一个节点(原来是该组最后一个节点)应该被上一组的最后一个节点连接上,这一组的最后一个节点(原来是该组第一个节点)应该连接下一个节点。然后继续去凑下一组,直到链表都被遍历完。

例如:链表3->2->1->4->5->6->7->8->null,k=3,第一组已处理完。第二组从栈顶到栈底依次为6,5,4.逆序重连之后为6->5->4,然后节点66应该被节点1连接,节点4应该连接节点7,链表变为3->2->1->6->5->4->7->8->null.然后继续从节点7往下遍历。

5.最后应该返回newHead,作为新的头节点。

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        if(k < 2) return head;
        Stack<ListNode> stack = new Stack<ListNode>();
        ListNode newHead =head;
        ListNode cur = head;
        ListNode pre = null;
        ListNode next = null;
        while(cur != null){
            next = cur.next;
            stack.push(cur);
            if(stack.size() == k){
                pre = resin1(stack,pre,next);
                newHead = newHead == head ? cur :newHead;
            }
            cur = next;
        }
        return newHead;
    }
    public ListNode resin1(Stack<ListNode> stack,ListNode left,ListNode right){
        ListNode cur = stack.pop();
        if(left != null){
            left.next = cur;
        }
        ListNode next = null;
        while(!stack.isEmpty()){
            next = stack.pop();
            cur.next = next;
            cur = next;
        }
        cur.next = right;
        return cur;
    }
}

但是,循环着做着同样的事,我们可以用一种方法来实现,是什么呢?当然是递归!

代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if(head == null || head.next == null){
            return head;
        }
        int count = 0;
        ListNode curr = head;
        while(count != k && curr != null){
            curr = curr.next;
            count++;
        }
        if(count == k){
            curr = reverseKGroup(curr,k); //上一次翻转后的头节点
            while(count -- > 0){ //翻转
                ListNode tmp = head.next;
                head.next = curr;
                curr = head;
                head = tmp;
            }
            head = curr;
        }
        return head;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值