链表随笔

链表数据结构:

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/

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

猜你喜欢

转载自www.cnblogs.com/luiyuying/p/12676299.html