题解 | #链表中的节点每k个一组翻转#

链表中的节点每k个一组翻转

http://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e

方法一:分块翻转

  • 将链表分块,每块的长度为k个元素,分块翻转。
  • 首先,计算链表长度,根据链表长度和k计算需要翻转多少块;
  • 之后,一块一块的翻转;
  • 最后,再将长度不足k的块接到翻转后的链表尾部。
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(head == null || k <= 1)
            return head;
        
        // 获取链表长度
        int len = getLength(head);
        // 分块
        int blocks = len / k; //都是int类型,向下取整
        ListNode result = new ListNode(-1);
        ListNode resultTail = result;
        // 一块一块的翻转
        ListNode cur = head;
        for(int i = 0; i < blocks; ++i){
            // 翻转第i+1个块
            ListNode pre = null;
            for(int j = 0; j < k; ++j){
                ListNode tmp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = tmp;
            }
            // 翻转后,pre为当前块的第一个节点,cur为新的块的第一个节点
            resultTail.next = pre; // 接到结果链表尾部
            while(resultTail.next != null)
                resultTail = resultTail.next; // 指向结果链表的尾节点
        }
        resultTail.next = cur; // 将长度不足k的最后一块接上
        return result.next;
    }
    
    private int getLength(ListNode list){
        ListNode cur = list;
        int len = 0;
        while(cur != null){
            len++;
            cur = cur.next;
        }
        return len;
    }
}

方法二:栈

  • 翻转问题:可以考虑用栈的后入先出的特点来解决;
  • 以k为单位,将元素入栈,之后以k为单位出栈,并将出栈的元素拼接到链表尾部;
  • 最后,将不足k个的元素接到链表尾部
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(head == null || k <= 1)
            return head;
        
        Deque<ListNode> stack = new ArrayDeque<>(); 
        ListNode result = new ListNode(-1);
        ListNode resultTail = result;
        ListNode cur = head;
        while(true){
            int count = 0;
            for(int i = 0; i < k; ++i){ // 每k个为一组,入栈
                stack.offerLast(cur);
                count++;
                cur = cur.next;
                if(cur == null) // 遍历结束
                    break;  // 跳出for
            }
            if(count == k){ // k个元素出栈,拼接到链表尾部
                while(!stack.isEmpty()){
                    resultTail.next = stack.pollLast();
                    resultTail = resultTail.next;
                    resultTail.next = null;
                }
            }
            if(cur == null) break; //跳出break;
        }
        while(!stack.isEmpty()){ // 不足k个的元素,接到链表尾部
            cur = stack.pollLast();
        }
        resultTail.next = cur;
        return result.next;
    }
}
全部评论

相关推荐

2025-12-08 07:42
门头沟学院 Java
27届末九,由于是女生,身边人几乎没有就业导向的,自学只能跟着网课,没人指导,很迷茫。下图是我目前的简历,不知道有需要修改的地方吗?求拷打。下面是目前的学习情况:目前算法过完了一遍力扣100和代码随想录,不过不是很熟,面经看了小林coding、JavaGuide,有一些没用过的技术看得不是很明白,掌握得不是很扎实。再加上常年跟黑马网课听思路,真正自己动手写代码的时间很少,这让我一直不敢投简历,总觉得内里空虚。项目没准备好面试相关的问题,简历上相应的考点不熟。如此种种。。。看到很多很多学长学姐大佬们的面经,愈发觉得面试可怕,自己没准备好,总担心自己是不是无望后端开发了。看到牛客很多同届以及更小一届的同学都找到实习了,很希望自己也能找到实习。而自己又好像摸不到后端学习的门路,只能不断赞叹黑马虎哥写的代码真优雅!微服务架构实在巧妙!消息队列、redis、sentinel、nacos、mybatisplus等等的引入都会让我赞叹这些工具的设计者的巧思,以及包括但不限于Java语言的优雅。然而只是停留在了解的程度,并不熟练。我是很希望能够继续深入探索这些知识的,只不过有一大部分时间都花在学校课程上了。我感觉我被困住了,我一方面必须保证我能够有个不错的学业分使我能有我几乎不想选择的读研退路(还有个原因是复习不全我会焦虑考试挂科,因此我会做好全面的准备,而这一步很费时间),一方面在B站学习各种网课,一方面得考虑提升自己并不扎实的算法基础,另一方面还得准备八股面经。这让我有点苦恼,我好像没那么多时间,因为绝大部分时间都花在了复习学校科目中了。我好像处处用时间,但收效甚微。想问问各位大佬是怎么平衡时间的呢?算法、项目和八股是怎么准备的呢?有什么高效的方法吗?谢谢您们花时间阅读我的稿件!
菜菜狗🐶:大胆投,我当时也是害怕面试,投多了发现根本约不到面🤡
点赞 评论 收藏
分享
牛客77743221...:做一段时间,公司出钱送你去缅甸和泰国旅游
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务