链表随笔
链表数据结构:
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/
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 太难。
==== nice day