美文网首页
算法学习笔记之初级链表

算法学习笔记之初级链表

作者: 芝士和饼干 | 来源:发表于2018-06-17 21:17 被阅读0次

    记录一下最近刷的比较有意思的题

    1. 环形链表

    给定一个链表,判断链表中是否有环。

    进阶

    你能否不使用额外空间解决此题?

    我的思路与解答(1ms):

    首先理解环形链表的概念,我开始以为只有一种,就是头尾相连的链表就是环形链表,如下图;


    图1

    但其实还有一种比较特殊一点的环形链表,如下图;


    图2
    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    class Solution {
        public boolean hasCycle(ListNode head) {
            if(head == null) return false;
            /** 
            *  主要思路:用双指针解法,slow和fast,都从头部开始
            *  slow每次走一步,fast每次走两步
            *  这样不论是头尾相连的环形链表还是特殊的环形链表
            *  在若干步后slow和fast会相遇
            */
            ListNode slow = head;
            ListNode fast = head;
            while(fast.next != null){
                slow = slow.next;
                fast = fast.next;
                if(fast.next != null){
                    fast = fast.next;
                }else{
                    return false;
                }
                if(slow.equals(fast)){
                    return true;
                }
            }
            return false;
        }
    }
    

    小结:

    一开始只想到了头尾相连的链表,去搜索了相关概念后才知道原来还有另一种,但是这题做起来思路还是比较明确。

    2. 合并两个有序链表

    将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    示例:

    输入: 1->2->4, 1->3->4
    输出: 1->1->2->3->4->4

    我的思路与解答(11 ms):

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            if(l1 == null && l2 == null) return null;
            if(l1 == null) return l2;
            if(l2 == null) return l1;
            ListNode head;
            ListNode p1;
            ListNode p2;
            ListNode temp;
            
            // 首先对比两个链表头部的值的大小,小的链表为最终返回的链表,即将头部大的拆开插入小的链表
            if(l1.val <= l2.val){
                head = l1;
                p1 = l1;
                p2 = l2;
            }else{
                head = l2;
                p1 = l2;
                p2 = l1;
            }
            
            /**
            *  进入循环,当判断p2指向的结点的值大于等于p1所指向且小于p1的下个结点的值时
            *  将p2所指向的结点插到p1之后,并将p1指向被插入的结点
            *  当p1或p2为最后一个结点时跳出循环
            */ 
            while(p1.next != null && p2.next != null){
                if(p2.val >= p1.val) {
                    if(p1.next.val > p2.val) {
                        temp = p1.next;
                        p1.next = p2;
                        l2 = p2.next;
                        p2.next = temp;
                        p1 = p2;
                        p2 = l2;
                        continue;
                    }
                    p1 = p1.next;
                }
            }
            
            /**
            *  这时会有两张情况:
            *  1. p2为最后一个结点,只需再进行一次循环,将p2插入链表
            *  2. p1为最后一个结点,说明链表的最大的值都没有比p2所指向的结点的值大,只需将p2插到链表的最后即可
            *     因为这时p1指向的是最后一个结点,所以直接 p1.next = p2 即可
            */
            if(p2.next == null){
                while(p1.next != null){
                    if(p2.val >= p1.val){
                        if(p1.next.val > p2.val) {
                            temp = p1.next;
                            p1.next = p2;
                            l2 = p2.next;
                            p2.next = temp;
                            p1 = p2;
                            p2 = l2;
                            return head;
                        }
                        p1 = p1.next;
                    }
                }
            }
            
            if(p1.next == null){
                p1.next = p2;
            }
            
            return head;
            
        }
    }
    

    小结:

    这题第一次做的时候思路很乱,做了一个晚上都没做出来,第二天再做的时候理清思路10分钟就做出来了,事实证明做题思路很重要

    3. 总结

    链表类的题目尤其需要思路明确,有一点错误就容易发生空指针异常。

    本文作者:RoNnx
    博客链接:http://ronnx.top/2018/06/17/20180004/
    版权声明:本作品采用「知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可」,转载请注明出处!

    相关文章

      网友评论

          本文标题:算法学习笔记之初级链表

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