zoukankan      html  css  js  c++  java
  • 链表随笔

    链表数据结构:

    public class LinkedList{
         int val;
         LinkedList next;
         public LinkedList(int val){this.val = val;}   
    }

    1翻转链表  Leetcode 206

    关键为对下一个next的备份,对上一个节点的记录(temp)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode reverseList(ListNode head) {
            if(head==null) return head;
            if(head.next == null) return head;
            ListNode next; //备份
            ListNode temp = null; 
            while(head!=null)
            {
                next=head.next;
                head.next = temp;
                temp=head;
                head=next;
            }
            return temp;
        }
    }

    2翻转链表2 Leetcode 92

    反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode reverseBetween(ListNode head, int m, int n) {
            if(head.next==null) return head;
    
            ListNode temphead = head;
            ListNode before = null;
            for(int i=0;i<m-1;i++) 
            {
                before = temphead;
                temphead = temphead.next;
            }
            ListNode begin = temphead;
            ListNode temp = null;
            ListNode tempbf = null;
            for(int i=0;i<n-m+1;i++)
            {
                temp = temphead.next;
                temphead.next=tempbf;
                tempbf=temphead;
                temphead=temp;
            }
            begin.next=temphead;
            if(before==null) return tempbf;  //注意是不是从第一个开始翻转
            else before.next = tempbf;
            return head;
    
        }
    }

    3求两个链表的交点 Leetcode 160 https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

    方法一 暴力法:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            ListNode a = headA;
            ListNode b = headB;
            while(a!=null)
            {
                b = headB;        
                while(b!=null)
                {    
                    if(a==b) 
                    {
                        return b;
                    }
                    b = b.next;
                }
                a = a.next;
            }
            return null;
        }
    }

    方法二 快慢指针:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            
            ListNode a = headA; 
            ListNode b = headB; 
            int lena =0;
            int lenb =0;
            while(a!=null)
            {
                lena++;
                a=a.next;
            }
            while(b!=null)
            {
                lenb++;
                b=b.next;
            }
            a=headA;
            b=headB;
            if(lena>lenb)
            {
                for(int i=0;i<lena-lenb;i++)
                {
                    a=a.next;
                }
            }
            else
            {
                for(int i=0;i<lenb-lena;i++)
                {
                    b=b.next;
                }
    
            }
            if(a==b) return a;
            do{
                a = a.next;
                b = b.next;
            }while(a!=b);
            if(a==null) return null;
            else return a;
        }
    }

    4链表求环 Leetcode141

    给定一个链表,判断链表中是否有环。快慢指针。

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public boolean hasCycle(ListNode head) {
            ListNode fast = head;
            ListNode slow = head;
            if(head==null||head.next==null) return false;
            
            while(fast!=null&&slow!=null)
            {
                fast = fast.next;
                if(fast!=null) fast = fast.next;
                else return false;
                slow = slow.next;
                if(slow==fast) return true;
            }
            return false;
        }
    }

    5链表求环2 leetcode142

    推导 快指针(2)走过的路程是慢指针(1)的两倍 则在h点相遇时 (F+a)*2+n*(a+b)= F+a+b+a+n*(a+b) 则F=b

    所以从head与h出发,能找到环的起始节点

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            ListNode fast = head;
            ListNode slow = head;
            ListNode meet = null;
            if(head==null||head.next==null) return null;
    
            while(fast!=null&&slow!=null)
            {
                fast=fast.next;
                if(fast!=null) fast = fast.next;
                else return null;
                slow = slow.next;
                if(fast==slow) 
                {
                    meet=fast;
                    break;
                }
            }
            if(meet!=null)
            {
                while(head!=meet)
                {
                    head=head.next;
                    meet=meet.next;
                }
                return meet;
            }
            return null;
        }
    }

    6分隔链表 leetcode 64

    给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

    你应当保留两个分区中每个节点的初始相对位置。

    使用临时节点保存

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode partition(ListNode head, int x) {
            ListNode small = null;
            ListNode smptr = null;
    
            ListNode large = null;
            ListNode lgptr = null;
            if(head==null) return null;
            while(head!=null)
            {
                
                if(head.val<x) 
                {
                    
                    if(small==null) 
                    {
                        small = head;
                        smptr = head;
                    }
                    else
                    {
                        smptr.next = head;
                        smptr = head;
                    }
                }
                else
                {
                    
                    if(large==null)
                    {
                        large = head;
                        lgptr = head;
                    }
                    else{
                        lgptr.next = head;
                        lgptr = head;
                    }
                }
                head = head.next;
            }
            
            
            if(small==null) return large;
            smptr.next = large;
            if(large!=null) lgptr.next = null;
            return small;
    
        }
    }

    7链表深拷贝 太难 leetcode 138

    8链表合并 leetcode 21

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

    /**
     * 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) {
            //应用临时节点
            ListNode newhead = null;
            ListNode ptr = null;
            if(l1==null) return l2;
            if(l2==null) return l1;
            while(l1!=null&&l2!=null)
            {
                if(l1.val<l2.val)
                {
                    if(newhead==null)
                    {
                        newhead = l1;
                        ptr = newhead;
                    }
                    else
                    {
                        ptr.next = l1;
                        ptr = l1;
                    }
                    l1 = l1.next;
                }
                else{
                    if(newhead==null)
                    {
                        newhead = l2;
                        ptr = newhead;
                    }
                    else
                    {
                        ptr.next = l2;
                        ptr = l2;
                    }
                    l2 = l2.next;
                }
            }
            if(l1==null)
            {
                ptr.next = l2;
                
            }
            else ptr.next = l1;
            return newhead;
        }
    }

    9合并链表2 Leetcode23 https://leetcode-cn.com/problems/merge-k-sorted-lists/

    合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 太难。

  • 相关阅读:
    javascript之Number
    javascript之window对象
    javascript全局对象
    javascript之尺寸,位置,溢出
    javascript之DOM操作
    javascript之全局函数
    javascript之Error
    javascript之url转义escape()、encodeURI()和decodeURI()
    javascript之Boolean
    javascript之Arguments
  • 原文地址:https://www.cnblogs.com/luiyuying/p/12676299.html
Copyright © 2011-2022 走看看