K个一组反转链表

记录一下链表的题
力扣题目链接: https://leetcode.cn/problems/reverse-nodes-in-k-group/

题目 : K个一组反转链表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例1:
请添加图片描述

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例2:
请添加图片描述

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

提示:

  • 链表中的节点数目为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

此问题的意思就是给你一个链表的起始位置,和一个数字k,让你找到k个数进行局部反转。
我们知道,如果知道一个链表的起始位置(头部),就可以计算出此后所有的元素。所以,我们最后的结果,也只需要返回一个head头结点即可。
后台的测试用例已经给出了定义链表的结构,所以我们直接用就行。

思路:

  • 我们首先要找出第k个节点吧,第k个节点怎么找? 我们需要两个参数,一个是头结点head,一个是k。
  • *那我们怎么知道什么时候结束找寻呢?当然是while循环让 k减一啦!
  • 那我们还要考虑什么?是不是如果头结点的 head.next 是null呢?是不是就说明,下一个数是没有的,我们竟然没有找到k个数,那怎么办呢,不用管,直接返回head就行,没找全,就返回原来指向的头结点呗。*
  • 我们写一个方法返回找到的k个数的节点。
public static ListNode getKGroup(ListNode start, int k){
        // 考虑边界
        while(--k != 0 && start != null){
            start = start.next; 
        }
        return start;
    }
  • 我们找到第k个数的节点了,然后我们就开始反转了,我们需要两个参数,一个是开始的节点,题目已经给出了,一个是第k个节点,我们也已经写出来了。
  • 再写一个反转的方法 ,代码已有注释。
 public static void reverse(ListNode start,ListNode end){
        end = end.next; // 保存结束的节点,他将作为下一轮新的节点的开始位置。
        ListNode pre = null;
        ListNode next = null;
        ListNode cur = start; // 记录当前开始的节点
        // 循环进行的条件,开始节点不等于结束节点的时候。
        while(cur != end){
            next = cur.next; // 先保存开始节点cur的next指针
            cur.next = pre; // 将当前的cur.next指针置空
            pre = cur;     // 把cur赋值给pre    
            cur = next;   // 再把保存的next节点赋值给cur
        }
        start.next = end; // 将start 指向 end 更新开始位置。
    }
看最终代码:
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode start = head;
        ListNode end = getKGroup(start,k);
        if(end == null){
            return head; // 没有凑齐一组
        }
        // 凑齐一组了
        head  = end;
        reverse(start,end);
        // 上一组的结尾节点
        ListNode lastEnd = start;
        while(lastEnd.next != null){
            start = lastEnd.next;
            end = getKGroup(start,k);
            if(end == null){
                return head;
            }
            reverse(start,end);
            lastEnd.next = end;
            lastEnd = start;
        }
        return head;
    }

    // 此方法给一个开始节点和k值,数够k个把数到的节点返回  
    public static ListNode getKGroup(ListNode start, int k){
        // 考虑边界
        while(--k != 0 && start != null){
            start = start.next; 
        }
        return start;
    }

    public static void reverse(ListNode start,ListNode end){
        end = end.next;
        ListNode pre = null;
        ListNode next = null;
        ListNode cur = start;
        while(cur != end){
            next = cur.next; // 先保存cur的next指针
            cur.next = pre; // 将当前的cur.next指针置空
            pre = cur; // 把cur赋值给pre    
            cur = next; // 再把保存的next指针赋值给cur
        }
        start.next = end; // 将start 指向 end
    }
}

OK! 打完收工!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值