zoukankan      html  css  js  c++  java
  • 反转链表进阶

    最近课程比较紧张,中秋放假休息了两天,回来继续刷算法题。链表翻转是个比较常见的类型,要吃透。

    力扣第92题:题目描述:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

    说明:1 ≤ m ≤ n ≤ 链表长度。

    示例:

    输入: 1->2->3->4->5->NULL, m = 2, n = 4
    输出: 1->4->3->2->5->NULL

    思路:

    用指针记录要反转区间的首尾节点,在写一个反转局部区间m到n的函数,在将反转后的链接起来

        public static ListNode reverseBetween(ListNode head, int m, int n) {
    
            if (m == n) return head;
            //创建头结点
            ListNode pHead = new ListNode(0);
            pHead.next = head;
            ListNode tail = pHead;
            //找到需要反转那一段的前一个节点
            for (int i = 1; i < m; i++)
                tail = tail.next;
            //局部反转链表的新起点
            ListNode nextHead = tail.next;
            ListNode pre = null;
            ListNode next = null;
            //反转n到m这一段,即反转n-m+1个节点
            for (int i = 0; i <= n - m; i++) {
                next = nextHead.next;
                nextHead.next = pre;
                pre = nextHead;
                nextHead = next;
            }
            //pre即为局部反转的链表头节点
            tail.next = pre;
            //找到反转链表的最后一个节点
            while (pre.next != null) {
                pre = pre.next;
            }
            //链接起来
            pre.next = next;
            return pHead.next;
        }

    力扣第25题:k个一组反转链表

    题目描述:

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

    k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

    示例:

    给定这个链表:1->2->3->4->5
    
    当 k = 2 时,应当返回: 2->1->4->3->5
    
    当 k = 3 时,应当返回: 3->2->1->4->5

    说明:

    • 你的算法只能使用常数的额外空间。
    • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    思路:用指针记录需要反转部分你的头尾节点,写一个局部反转的函数,每k个反转一次,不够K个就返回

    public static ListNode reverseKGroup(ListNode head, int k) {
           if(head==null||head.next==null||k<=1)
               return head;
           ListNode currentNode = head;
           //获取k个元素的首尾节点
            for(int count=1;count<k;count++){
                currentNode = currentNode.next ;
                //不够k个就返回
                if(currentNode==null)
                    return head;
            }
            ListNode next = currentNode.next;
            //对局部链表进行反转
            reverse(head,currentNode);
            //递归接着每K个反转一次
            head.next = reverseKGroup(next,k);
            return currentNode;
        }
    
     public static ListNode reverse(ListNode head,ListNode tail){
            if(head==null||head.next==null)
                return head;
            ListNode pre = null;
            ListNode next = null;
            while(pre!=tail){
                next = head.next;
                head.next = pre;
                pre = head;
                head = next;
            }
            return head;
        }

    力扣第143题:重排链表

    题目描述:

    给定一个单链表 LL0→L1→…→L**n-1→Ln , 将其重新排列后变为: L0→L**nL1→L**n-1→L2→L**n-2→…

    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    示例:

    给定链表 1->2->3->4, 重新排列为 1->4->2->3.
    给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

    思路:寻找到链表的中间节点,将链表分为两段,将后半部分反转,在将两个链表合并

     public static void reorderList(ListNode head) {
            if (head == null || head.next == null)
                return;
            ListNode p1 = head;
            ListNode p2 = head;
            //寻找到链表的中间节点
            while (p2.next != null && p2.next.next != null) {
                p1 = p1.next;
                p2 = p2.next.next;
            }
            //将链表分为两段
            p2 = p1.next;
            p1.next = null;
            p1 = head;
            //将后半段链表进行反转
            ListNode pre = null;
            ListNode next = null;
            ListNode head2 = p2;
            while (head2 != null) {
                next = head2.next;
                head2.next = pre;
                pre = head2;
                head2 = next;
            }
            p2 = pre;
            //合并两个链表
            ListNode next1;
            ListNode next2;
            while (p2 != null) {
                next1 = p1.next;
                next2 = p2.next;
                p1.next = p2;
                p2.next = next1;
                p1 = next1;
                p2 = next2;
            }
        }
  • 相关阅读:
    iOS 文件操作--归档和解档
    iOS中UITabBarController的使用
    Objective-C基础知识点总结,字符串操作,数组操作,字典操作
    Objective-C中协议和分类总结
    Objective-C文件操作之NSCoding协议之小练习
    浅谈Objective-C继承和多态
    Objective-C内存管理基础知识
    MySort(选做)的实现
    20175308 2018-2019-2 实验四 《Android开发基础》实验报告
    JAVA 第十一周学习总结
  • 原文地址:https://www.cnblogs.com/zengcongcong/p/11521719.html
Copyright © 2011-2022 走看看