代码随想录算法训练营第四天|LeetCode 24,19, 面试题 02.07,142

目录

LeetCode 24.两两交换链表中的节点 

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

LeetCode 面试题 02.07.链表相交

LeetCode 142.环形链表 II


LeetCode 24.两两交换链表中的节点 

文章讲解:代码随想录

视频讲解:帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili

力扣题目:LeetCode 24.两两交换链表中的节点 

 

 初看思路:不交换值,而进行交换节点,那必然涉及到指针的操作,那么就需要一个或多个新节点来存储临时值。需要多少个新节点,那就需要画图来思考总结规律了。

图片如下:

 之前我们学过操作链表的时候,在链表中添加节点或者删除节点,往往有一个虚拟节点会很好统一操作,这里我们也先设置一个虚拟节点,并且把这个虚拟节点指向头节点。

接下来,我们则需要交换元素为1和元素为2的节点。在这个过程中,dummyhead需要指向2节点,在指向节点2的同时,我们就无法获取节点1的位置,所以在操作dummyhead指针的之前此时需要一个节点temp来存储节点1。 

 

 那么这个时候我们就可以使节点2指向节点1也即是temp,但是此时问题又来了,当节点2指向节点1的时候,我们就无法获取节点3的位置,所以在操作dummyhead指针之前这里也需要一个节点tempTwo来存储节点3。

 最后我们可以在把节点1(也即是temp)指向节点3(也即是tempTwo),我们就可以反转节点1和节点2的位置,之后就要移动cur指针到需要反转节点的前面的位置。

 之后就需要判断循环的终止条件,通过上面我们可以知道,移动的是cur指针,当链表中的节点数量为偶数是,cur.next就会为null;当链表中的节点数量为奇数时,最后一个节点就不需要反转,那么此时cur.next.next也会为null。所以综上所述,判断条件就可以为

while(cur.next != null && cur.next.next != null){}

代码如下(Java):

/**
 * 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;
        //创建临时temp节点
        ListNode temp = new ListNode();
        //创建临时tempTwo节点
        ListNode tempTwo = new ListNode();
        //创建cur节点指向虚拟头节点
        ListNode cur = dummyHead;

        while(cur.next != null && cur.next.next != null){
            
            temp = cur.next;
            tempTwo = cur.next.next.next;
            cur.next = cur.next.next;
            cur.next.next = temp;
            temp.next = tempTwo;
            cur = cur.next.next;

        }

        return dummyHead.next;

    }
}

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

文章讲解:代码随想录

视频讲解:链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点_哔哩哔哩_bilibili

力扣题目:LeetCode 19.删除链表的倒数第N个结点 

代码如下(Java):

/**
 * 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();
        ListNode cur = dummyHead;
        dummyHead.next = head;
        int length = 0;

        //统计链表的长度
        while(cur.next != null){
            length++;
            cur = cur.next;
        }


        cur = dummyHead;

        //定位要删除节点的前一个位置
        length -= n;

        //length为零说明,要删除的节点为头节点
        if(length == 0){
             cur.next = cur.next.next;
        }else{
            //定位要删除节点的前一个位置
            for(int i = 0; i < length; i++){
                cur = cur.next;
            }

            //找到之后进行删除节点操作
            cur.next = cur.next.next;
        }

        return dummyHead.next;
    }
}

使用快慢指针的解法(Java):

/**
 * 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 fastIndex = dummyHead;
        ListNode slowIndex = dummyHead;


        //想要slowIndex节点位于删除元素的起一个位置,那么此时fastIndex就会和slowIndex节点的位置相差n
        //所以先让fastIndex节点走n步
        while(n-- != 0 && fastIndex.next != null){
            fastIndex = fastIndex.next;
        }

        //该循环是把slowIndex节点放在要删除节点的前一个节点当中
        //此时fastIndex节点也位于尾节点
        while(fastIndex.next != null){
            slowIndex = slowIndex.next;
            fastIndex = fastIndex.next;
        }

        //进行删除节点的操作
        slowIndex.next = slowIndex.next.next;
        

        return dummyHead.next;
    }
}

LeetCode 面试题 02.07.链表相交

文章讲解:代码随想录

力扣题目: LeetCode 面试题 0 LeetCode 面试题 02.07.链表相交 LeetCode 面试题 0

 代码如下(Java):代码随想录

/**
 * 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){
            lenA++;
            curA = curA.next;
        }

        while(curB != null){
            lenB++;
            curB = curB.next;
        }

        curA = headA;
        curB = headB;

        if(lenB > lenA){
            
            int temp = lenA;
            lenA = lenB;
            lenB = temp;

            ListNode tempNode = curA;
            curA = curB;
            curB = tempNode;
        }

        int gapLen = lenA - lenB;

        while(gapLen-- > 0){
            curA = curA.next;
        }

        while(curA != null && curB != null){

            if(curA == curB){
                return curA;
            }

            curA = curA.next;
            curB = curB.next;
        }

        return null;

    }
}

LeetCode 142.环形链表 II

文章讲解:代码随想录

视频讲解:把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili

力扣题目: LeetCode 142.环形链表 II

 

 代码如下(Java):

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

        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值