[LeetCode][链表翻转]reverse nodes in k group【java】

1.题目

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For 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

 

2.思路

每k个一组  翻转链表 

在一个函数中完成,我们首先遍历整个链表,统计出链表的长度,然后如果长度大于等于k,我们开始交换节点,当 k=2 时,每段我们只需要交换一次,当 k=3 时,每段需要交换2此,所以i从1开始循环,注意交换一段后更新 pre 指针,然后 num 自减k,直到 num<k 时循环结束 

 

3.解法1:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        //链表反转
        ListNode root = new ListNode(0);
        root.next = head;
        ListNode res = root;
        ListNode tmp = head;
        int i = 0;
        while(tmp != null){//计算链表长度
            i++;
            tmp = tmp.next;
        }
        while(i >= k){
            for(int j = 0;j<k-1;j++){
                ListNode node = root.next;
                root.next = head.next;
                head.next = root.next.next;
                root.next.next =node;
            }
            root = head;
            head = head.next;
            i-=k;
        }
        return res.next;
        
    }
}

解法2:

一般在处理链表问题时,我们大多时候都会在开头再加一个 dummy node,因为翻转链表时头结点可能会变化,为了记录当前最新的头结点的位置而引入的 dummy node  那么我们加入 dummy node 后的链表变为 -1->1->2->3->4->5,如果k为3的话,我们的目标是将 1,2,3 翻转一下,那么我们需要一些指针,pre 和 next 分别指向要翻转的链表的前后的位置,然后翻转后 pre 的位置更新到如下新的位置:

-1->1->2->3->4->5
 |        |  |
pre      cur next

-1->3->2->1->4->5
    |     |  |
   cur   pre next

 

以此类推,只要 cur 走过k个节点,那么 next 就是 cur->next,就可以调用翻转函数来进行局部翻转了,注意翻转之后新的 cur 和 pre 的位置都不同了,那么翻转之后,cur 应该更新为 pre->next,而如果不需要翻转的话,cur 更新为 cur->next,代码如下所示:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        //链表反转
        /*ListNode root = new ListNode(0);
        root.next = head;
        ListNode res = root;
        ListNode tmp = head;
        int i = 0;
        while(tmp != null){//计算链表长度
            i++;
            tmp = tmp.next;
        }
        while(i >= k){
            for(int j = 0;j<k-1;j++){
                ListNode node = root.next;
                root.next = head.next;
                head.next = root.next.next;
                root.next.next =node;
            }
            root = head;
            head = head.next;
            i-=k;
        }
        return res.next;*/
        
        
         if(head==null||k==1)
        return head;
 
        ListNode fake = new ListNode(0);
        fake.next = head;
        ListNode prev = fake;
        int i=0;

        ListNode p = head;
        while(p!=null){
            i++;
            if(i%k==0){
                prev = reverse(prev, p.next);
                p = prev.next;
            }else{
                p = p.next; 
            }
        }

        return fake.next;  
    }
    public ListNode reverse(ListNode prev, ListNode next){
        ListNode last = prev.next;
        ListNode curr = last.next;

        while(curr != next){//翻转段内的链表
            last.next = curr.next;
            curr.next = prev.next;
            prev.next = curr;
            curr = last.next;
        } 
        return last; 
}

    
}

 

参考:https://www.cnblogs.com/grandyang/p/4441324.html

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值