代码随想录算法训练营第四天【链表】24.两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07.链表相交、142.环形链表II

24.两两交换链表中的节点
力扣题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/
心得:关键是定义虚拟头结点、理清循环终止条件,交换的顺序,避免出现空指针、死循环。本题看视频理清思路之后,很快做出来了。
复制代码
/**
 * 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 swapPairs(ListNode head) {
        ListNode dummyHead = new ListNode();
        dummyHead.next = head;
        ListNode cur = dummyHead;
        ListNode temp1;
        ListNode temp2;
        while(cur.next!=null && cur.next.next!=null){
            temp1 = cur.next;
            temp2 = cur.next.next.next;
            cur.next = cur.next.next;
            cur.next.next = temp1;
            temp1.next = temp2;
            cur = temp1;
        }
        return dummyHead.next;
    }
}
复制代码

19.删除链表的倒数第N个节点

力扣题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/submissions/

心得:关键在于怎么找到“倒数第N个节点的前一个节点”,双指针思想太妙了。

  1)分析倒数第N个节点的特征:该节点之后的第N个节点一定为null

  2)slow来代表目标节点,fast来代表目标节点后的第N个节点

  3)slow的起始位置是虚拟节点,用for循环计算n次,找到fast的初始节点

  4)目标节点slow应该是要删除节点的前一个节点,因此fast也是null的前一个节点,所以当fast.next != null时,slow和fast就不断向后移动

  5)找到目标节点,自然就可以轻松删除了

复制代码
/**
 * 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 removeNthFromEnd(ListNode head, int n) {
        ListNode dummyHead = new ListNode();
        dummyHead.next = head;
        ListNode slow = dummyHead;
        ListNode fast = dummyHead;
        for(int i=0;i<n;i++){
            fast = fast.next;
        }
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return dummyHead.next;
    }
}
复制代码

面试题 02.07.链表相交

力扣题目链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/

心得:思考了十分钟没什么思路,果断看题解了。核心思路就是让两个链表末尾对齐!然后从较短的头结点开始遍历比较,匹配到就返回当前节点,到最后也没有相同节点则返回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 curA = headA;
        ListNode curB = headB;
        int lenA = 0;
        int lenB = 0;
        while(curA != null){
            curA = curA.next;
            lenA++;
        }
        while(curB != null){
            curB = curB.next;
            lenB++;
        }
        int len = 0;
        ListNode curLong;
        ListNode curShort;
        if(lenA > lenB){
            curLong = headA;
            curShort = headB;
            len = lenA-lenB;
        }else{
            curLong = headB;
            curShort = headA;
            len = lenB-lenA;
        }
        while(len-- > 0){
            curLong = curLong.next;
        }
        while(curLong != null){
            if(curLong == curShort){
                return curLong;
            }
            curLong = curLong.next;
            curShort = curShort.next;
        }
        return null;
    }
}
复制代码

142.环形链表II

力扣题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/submissions/

心得:本题的重点是快慢指针,通过数学公式推导出步长的关系。

  1)(x + y) * 2 = x + y + n (y + z)  =>  x = (n - 1) (y + z) + z

  2)寻到快慢指针相遇点

  3)寻到开始入环的节点

复制代码
/**
 * 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 slow = head;
        ListNode fast = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                ListNode index1 = fast;
                ListNode index2 = head;
                while(index1 != index2){
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1; 
            }
        }
        return null;
    }
}
复制代码

 

posted @   橙子的房东  阅读(352)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示