zoukankan      html  css  js  c++  java
  • k个一组翻转链表(leetcode25)

    给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

    k 是一个正整数,它的值小于或等于链表的长度。

    如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    进阶:

    你可以设计一个只使用常数额外空间的算法来解决此问题吗?
    你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    示例

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

    解析:

    我们需要把链表节点按照 k 个一组分组,所以可以使用一个指针 head 依次指向每组的头节点。这个指针每次向前移动 k 步,直至链表结尾。对于每个分组,我们先判断它的长度是否大于等于 k。若是,我们就翻转这部分链表,否则不需要翻转。

    接下来的问题就是如何翻转一个分组内的子链表。但是对于一个子链表,除了翻转其本身之外,还需要将子链表的头部与上一个子链表连接,以及子链表的尾部与下一个子链表连接。

    因此,在翻转子链表的时候,我们不仅需要子链表头节点 head,还需要有 head 的上一个节点 pre,以便翻转完后把子链表再接回 pre

    但是对于第一个子链表,它的头节点 head 前面是没有节点 pre 的。太麻烦了!难道只能特判了吗?答案是否定的。没有条件,我们就创造条件;没有节点,我们就创建一个节点。我们新建一个节点,把它接到链表的头部,让它作为 pre 的初始值,这样 head 前面就有了一个节点,我们就可以避开链表头部的边界条件。

    public class leetcode25 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            ListNode item5 = new ListNode(5);
            ListNode item4 = new ListNode(4,item5);
            ListNode item3 = new ListNode(3,item4);
            ListNode item2 = new ListNode(2,item3);
            ListNode item1 = new ListNode(1,item2);
            int k = 2;
            
            ListNode ans = reverseKGroup(item1,2);
            ans.printNode(ans);
        }
        
        public static ListNode reverseKGroup(ListNode head,int k){
            ListNode hair = new ListNode(0);
            hair.next = head;
            ListNode pre = hair;
            
            while(head!=null){
                ListNode tail = pre;
                //查看剩余部分长度是否大于大于k
                for(int i=0;i<k;i++){
                    tail = tail.next;
                    if(tail==null){
                        return hair.next;//返回结果,对不够k个长度的链表不做翻转
                    }
                }
                ListNode nex = tail.next;
                ListNode[] reverse = myReverse(head,tail);
                head = reverse[0];
                tail = reverse[1];
                //把子链表重新接回原链表
                pre.next = head;
                tail.next = nex;
                pre = tail;
                head = tail.next;
            }
            return hair.next;
        }
        //翻转链表
        public static ListNode[] myReverse(ListNode head,ListNode tail){
            ListNode prev = tail.next;//作为prev指针:上一个
            ListNode curr = head;//作为curr指针:当前
            while(prev!=tail){
                ListNode nex = curr.next;
                curr.next = prev;
                prev = curr;
                curr = nex;
            }
            return new ListNode[]{tail,head};
        }
    
    }
  • 相关阅读:
    83. Remove Duplicates from Sorted List
    35. Search Insert Position
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    111. Minimum Depth of Binary Tree
    169. Majority Element
    171. Excel Sheet Column Number
    190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/14502683.html
Copyright © 2011-2022 走看看