美文网首页
LC链表题目分类详解

LC链表题目分类详解

作者: Aaron_Swartz | 来源:发表于2019-10-05 11:57 被阅读0次
    • 基础知识
    • 链表翻转
     public static MyNode reverseList(MyNode node) {
            if (node == null) return node;
            MyNode pre = node;//上一节点
            MyNode cur = node.getNext();//当前节点
            MyNode temp;// 临时结点,用于保存当前结点的指针域(即下一结点)
            while (cur != null) {
                temp = cur.getNext();
                cur.setNext(pre);// 反转指针域的指向
                // 指针往下移动
                pre = cur;
                cur = temp;
            }
            // 最后将原链表的头节点的指针域置为null,还回新链表的头结点,即原链表的尾结点
            node.setNext(null);
            return pre;
        }
    
    实际做的事情

    实际应用
    1 LeetCode] Plus One Linked List 链表加一运算

    • 如何在O(n) 和 O(1)的时间复杂度下删除链表
      参考 3

    leetcode 链表题目解答

    • leetcode 21 合并有序链表
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode p = l1;
            ListNode q = l2;
            ListNode head = new ListNode(-1);
            ListNode cur = head;
            while (p != null && q != null) {
                int val;
                if (p.val <= q.val) {
                    val = p.val;
                    p = p.next;  
                } else {
                    val = q.val;
                    q = q.next;
                }
                cur.next = new ListNode(val);
                cur = cur.next;
            }
            if (p != null) { // **注意: 这里不用while循环,直接一个if判断 + next表示就可以了。 **
                cur.next = p;
            }
            if (q != null) {
                cur.next = q;
            }
            return head.next;
        }
    }
    
    • leetcode 83 删除链表中重复元素
      • 我的解法:总体略显复杂
    class Solution {
        public ListNode deleteDuplicates(ListNode head) {
            ListNode cur = head;
            while (cur != null) {
                ListNode curNext = cur.next;
                while (curNext != null && cur.val == curNext.val) {
                    curNext = curNext.next;
                }
                if (curNext == null) {
                    cur.next = null;
                    break;
                }
                cur.next = curNext;
                cur = cur.next;
            }
            return head;
        }
    }
    
    • 大神解法
    class Solution {
        public ListNode deleteDuplicates(ListNode head) {
            ListNode cur = head;
            while(cur != null && cur.next != null) {
                if(cur.val == cur.next.val) {
                    cur.next = cur.next.next;  // 执行删除重复节点
                } else {
                    cur = cur.next;  // 这个直到出现值不相同的节点的时候才向后移动,执行cur = cur.next;
                }
            }
            return head;
        }
    }
    
    image.png
    • leetcode 141
    // 自己AC,  判断链表中是否有环: 快慢指针
    public class Solution {
        public boolean hasCycle(ListNode head) {
            if (head == null) return false;
            ListNode cur = head;
            ListNode p = head.next;
            while ( cur != null && p != null) {
                if (p == cur) return true;
                p = p.next;
                if (p == cur) return true;
                if (p == null) return false;
                p = p.next;
                cur = cur.next;
            }
            return false;
        }
    }
    
    • 大神简洁解法

    快慢指针原理:快指针一次走两步,慢指针一次走一步,这样快指针每次比慢指针多走一步(+1), 因为是连续的,所以肯定会出现快慢指针相遇的情形,如果相遇则表示有环。

    public boolean hasCycle(ListNode head) {
            ListNode slow = head;
            ListNode quick = head;
            while (quick != null && quick.next != null) {  // 一定是quick和quick.next 作为判断条件
                quick = quick.next.next;
                slow = slow.next;
                if (quick == slow) return true;
            }
            return false;
         }
    
    • leetcode 142: 环形链表2
      • 自己的一个解法:太慢
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            ListNode slow = head; 
            ListNode fast = head;
            ListNode cur = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if (slow == cur) return cur;
                if (slow == fast) {
                    cur = cur.next;    
                }
            }
            return null;
        }
    }
    
    AC详情
    • 实际的解法其实是一个数学问题: 具体详解见参考4
    // 最后AC的解法
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            ListNode slow = head, fast = head;
            ListNode cur = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if (slow == fast) { // 有环的判断条件
                    break;    
                }
            }
            if (fast == null || fast.next == null) { // 无环的判断条件
                return null;
            }
            while (cur != slow) {
                cur = cur.next;
                slow = slow.next;
            }
            return cur;
        }
    }
    
    运行效果
    • leetcode 92
    class Solution {
        public ListNode reverseBetween(ListNode head, int m, int n) {
            
            if (head == null) return head;
            
            ListNode cur = head, pre = null; // 标记访问的节点
            
            while (m > 1) {
                --m;
                --n;
                pre = cur;
                cur = cur.next;
            }
            
            ListNode con = pre,  tail = cur;
            ListNode third; 
            while (n > 0) {
                --n;
                third = cur.next;
                cur.next = pre;
                pre = cur;
                cur = third;
            }
            if (con != null) {
                con.next = pre;    
            } else {
                head = pre;
            }
            tail.next = cur;
            return head;
        }
    }
    
    图解

    参考:
    1 链表翻转
    2 LeetCode Plus One Linked List 链表加一运算
    3 时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法
    4 快慢指针寻找入口点的解法

    相关文章

      网友评论

          本文标题:LC链表题目分类详解

          本文链接:https://www.haomeiwen.com/subject/xozxiqtx.html