目录
1.反转链表(leetcode206)
编辑
2. 链表内指定区间反转(leetcode92)
3.链表中的节点每k个一组翻转(leetcode25)
4.合并两个排序的链表(leetcode21)
5.链表的中间节点(leetcode876)
6.重排链表(leetcode143)
7.旋转链表(leetcode61)
8.删除排序链表中的重复元素(leetcode83)
9.删除排序链表中的重复元素(LeetCode 82)(迭代版)
10.环形链表 II ( LeetCode 142 )
11.回文链表( LeetCode 234 )
12.相交链表( LeetCode 160 )
13.奇偶链表( LeetCode 328 )
14.移除链表元素( LeetCode 203 )
15.链表题目做题总结
1.反转链表(leetcode206)


import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        // write code here
        ListNode prev=null;
        ListNode cur=head;
        if(head==null){
            return null;
        }
        if(head.next==null){
            return head;
        }
        while(cur!=null){
            ListNode temp=cur.next;
            cur.next=prev;
            prev=cur;
            cur=temp;
        }
        return prev;
    }
}2. 链表内指定区间反转(leetcode92)



import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode reverseBetween (ListNode head, int m, int n) {
        // write code here
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode prev=dummy;
        for(int i=0;i<m-1;i++){
            prev=prev.next;
        }
        ListNode cur=prev.next;
        for(int i=0;i<n-m;i++){
            ListNode temp=cur.next;
            cur.next=temp.next;
            temp.next=prev.next;
            prev.next=temp;
        }
        return dummy.next;
    }
}3.链表中的节点每k个一组翻转(leetcode25)


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head ListNode类
     * @param k int整型
     * @return ListNode类
     */
    public ListNode reverseKeyGroup (ListNode head, int k) {
        // write code here
       ListNode tail=head;
       //1.递归结束的点
        for (int i = 0; i < k; i++) {
            if(tail==null){
                return head;
            }
            tail=tail.next;
        }
        //2.完成每k个元素内的翻转
        ListNode prev=null;
        ListNode cur=head;
        while (cur!=tail){
            ListNode temp=cur.next;
            cur.next=prev;
            prev=cur;
            cur=temp;
        }
        head.next=reverseKeyGroup(tail,k);
        return prev;
    }
}4.合并两个排序的链表(leetcode21)


import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead1 ListNode类 
     * @param pHead2 ListNode类 
     * @return ListNode类
     */
    public ListNode Merge (ListNode pHead1, ListNode pHead2) {
        // write code here
        ListNode dummy =new ListNode(-1);
        ListNode prev=dummy;
        while(pHead1!=null && pHead2!=null){
            if(pHead1.val<pHead2.val){
                prev.next=pHead1;
                pHead1=pHead1.next;
                 prev=prev.next;
            }else{
                prev.next=pHead2;
                pHead2=pHead2.next;
                 prev=prev.next;
            }
        }
        if(pHead1!=null){
            prev.next=pHead1;
        }
        if(pHead2!=null){
            prev.next=pHead2;
        }
        return dummy.next;
    }
}5.链表的中间节点(leetcode876)

解题:快慢指针

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null && fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow;
    }
}
6.重排链表(leetcode143)
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        //1.快慢指针找到中间节点,分成左右两个链表
        ListNode leftHead=head;
        ListNode mid=midNode(head);
        ListNode rightHead=mid.next;
        //断开左右两个链表
        mid.next=null;
        //2.反转右边的链表
       rightHead=reverse(rightHead);
        //3.交错合并左右链表
        while(leftHead!=null && rightHead!=null){
            ListNode leftHeadNext=leftHead.next;
            ListNode rightHeadNext=rightHead.next;
            leftHead.next=rightHead;
            leftHead=leftHeadNext;
            rightHead.next=leftHead;
            rightHead=rightHeadNext;
        }
    }
    public ListNode midNode(ListNode head){
        ListNode slow=head;
        ListNode fast=head;
        while(fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
    public ListNode reverse(ListNode head){
        ListNode prev=null;
        ListNode cur=head;
        if(head==null){
            return null;
        }
        if(head.next==null){
            return head;
        }
        while(cur!=null){
            ListNode temp=cur.next;
            cur.next=prev;
            prev=cur;
            cur=temp;
        }
        return prev;
    }
}7.旋转链表(leetcode61)
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if(head==null || k==0){
            return head;
        }
        //计算出链表的长度,当k非常大时,走k步等于走k%len步
        ListNode cur=head;
        int len=0;
        while(cur!=null){
            len+=1;
            cur=cur.next;
        }
        k=k%len;
        //former指针先走k步
        ListNode former=head;
        ListNode later=head;
        for(int i=0;i<k;i++){
            former=former.next;
        }
        while(former.next!=null){
            former=former.next;
            later=later.next;
        }
        former.next=head;
        ListNode newHead=later.next;
        later.next=null;
         return newHead;
    }
}8.删除排序链表中的重复元素(leetcode83)
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode cur=head;
        if(head==null || head.next==null){
            return head;
        }
        while(cur!=null && cur.next!=null){
            if(cur.val==cur.next.val){
                cur.next=cur.next.next;
            }else{
                cur=cur.next;
            }
        }
        return head;
    }9.删除排序链表中的重复元素(LeetCode 82)(迭代版)
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

也可以使用递归的方式,个人认为迭代的方式更容易理解。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
         ListNode dummy=new ListNode(-1);
         dummy.next=head;
         ListNode cur=dummy;
         while(cur.next!=null && cur.next.next!=null){
            if(cur.next.val==cur.next.next.val){
                int value=cur.next.val;
                while(cur.next!=null && cur.next.val==value){
                    cur.next=cur.next.next;
                }
            }else{
                cur=cur.next;
            }
         }
         return dummy.next;
    }
}10.环形链表 II ( LeetCode 142 )
给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。


/**
 * 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;
        while(fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        
        if(fast==slow){
            ListNode b=fast;
            ListNode a=head;
            while(a!=b){
                a=a.next;
                b=b.next;
            }
            return a;
        }
     }
        return null;
    }
}11.回文链表( LeetCode 234 )
给你一个单链表的头节点 head ,请你判断该链表是否为
回文链表
。如果是,返回 true ;否则,返回 false 。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head.next==null){
            return true;
        }
        if(head.next.next==null){
            if(head.val==head.next.val){
                return true;
            }else{
                return false;
            }
        }
    //1.找到中间节点
    ListNode fast=head;
    ListNode slow=head;
    while(fast.next!=null && fast.next.next!=null){
        fast=fast.next.next;
        slow=slow.next;
    }
    //2.分割为两个链表
    ListNode leftHead=head;
    ListNode rightHead=slow.next;
    //3.反转右边链表
    rightHead= reverse(rightHead);
    //4.比较左右链表
    while (rightHead!=null){
    if(leftHead.val==rightHead.val){
        leftHead=leftHead.next;
        rightHead=rightHead.next;
    }else{
        return false;
    }
   }
   return true;
    }
    public ListNode reverse(ListNode head){
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
}12.相交链表( LeetCode 160 )
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。

/**
 * 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 pa=headA;
        ListNode pb=headB;
        if(headA==null || headB==null){
            return null;
        }
        while(pa!=pb){
            if(pa==null){
                pa=headB;
            }else{
                pa=pa.next;
            }
            if(pb==null){
                pb=headA;
            }else{
                pb=pb.next;
            }
        }
        return pa;
    }
}13.奇偶链表( LeetCode 328 )
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        //链表为空或者只有一个节点,直接返回即可
        if(head==null || head.next==null){
            return head;
        }
        ListNode odd=head;
        ListNode even=odd.next;
        ListNode evenHead=even;
        while(even!=null && even.next!=null){
            odd.next=even.next;    
            odd=odd.next;
            even.next=odd.next;
            even=even.next;
            }
            odd.next=evenHead;
            return head;
    }
}14.移除链表元素( LeetCode 203 )
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head==null){
            return null;
        }
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode pre=dummy;
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==val){
                pre.next=cur.next;
            }else{
                pre=cur;
            }
            cur=cur.next;
        }
        return dummy.next;
    }
}15.链表题目做题总结
 1.画图理清思路:
 2.考虑边界条件:链表问题通常有很多边界条件需要考虑,例如空链表、只有一个节点的链表、链表长度为偶数或奇数等等。双指针技巧:
 3.快慢指针:用于找链表中点、检测环等问题。
    双指针一前一后:用于逆转链表、找倒数第k个节点等问题。
    双指针同向移动:用于合并两个有序链表等问题。
 4.递归的应用:
 有些链表问题可以通过递归来简化处理,例如逆转链表、检测回文链表等。
 5.注意内存管理:
    如果涉及到链表节点的删除或插入,要确保不会造成内存泄漏或者指针丢失。特别是在删除节点时,要注意处理好被删除节点的前驱和后继节点的指针关系。
 6.利用哨兵节点简化操作:
    在一些操作中,使用哨兵节点(dummy node)可以简化边界条件的处理,特别是在涉及头节点操作时特别有效。
  




















