首页 > 其他分享 >代码随想录-链表相交

代码随想录-链表相交

时间:2024-10-23 11:48:23浏览次数:8  
标签:ListNode int 随想录 相交 next 链表 curB curA

题解与说明

要注意区分链表相交是指针相等,而不是值相等。

这里当时没有想清楚,还以为leetcode的样例一给错了,原来人家是想强调这个问题哈哈

这里给出三种解法:(leetcode格式)

① 看了代码随想录的解释后,自己写的代码。

② 看了代码随想录的代码后,对原有的代码循环进行优化。

③在代码随想录学习到的一种精简代码写法。

解法一:

/**
 * 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) {
        //先找到链表的长度距离之差
        int lenA = 0,lenB=0;
        ListNode curA = headA;
        ListNode curB = headB;
        while(curA!=null){
            lenA++;
            curA = curA.next;
        }
        while(curB!=null){
            lenB++;
            curB = curB.next;
        }
        int subLen = Math.abs(lenA-lenB);
        curA = headA;
        curB = headB;
        if(lenA>lenB){
            for(int i=0;i<subLen;i++){
                curA = curA.next;
            }
        }else{
            for(int i=0;i<subLen;i++){
                curB = curB.next;
            }
        }
        //A\B两个链表对齐了,一同向后走  寻找第一个相交结点(注意交点的定义是指针相同,而不是数值相同)
        while(curA!=curB){
            curA = curA.next;
            curB = curB.next;
        }
        return curA;

    }
}

解法二:

简化了移动比较次数,谁长谁是A。②优化了遍历方式,更加的简洁。

/**
 * 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) {
        //先找到链表的长度距离之差
        int lenA = 0,lenB=0;
        ListNode curA = headA;
        ListNode curB = headB;
        while(curA!=null){
            lenA++;
            curA = curA.next;
        }
        while(curB!=null){
            lenB++;
            curB = curB.next;
        }
        // int subLen = Math.abs(lenA-lenB);
        curA = headA;
        curB = headB;
       
        // if(lenA>lenB){
        //     for(int i=0;i<subLen;i++){
        //         curA = curA.next;
        //     }
        // }else{
        //     for(int i=0;i<subLen;i++){
        //         curB = curB.next;
        //     }
        // }
         //这里不再比较两次,而是谁长谁是A,交换指针和长度
        if(lenB>lenA){
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
        int subLen = lenA - lenB;
        while(subLen-->0){
            curA = curA.next;
        }
        //A\B两个链表对齐了,一同向后走  寻找第一个相交结点(注意交点的定义是指针相同,而不是数值相同)
        while(curA!=curB){
            curA = curA.next;
            curB = curB.next;
        }
        return curA;

    }
}

解法三:双指针

这里对双指针法加一下讲解,如果有不对的欢迎大家指正

双指针法两个指针pA和pB分别在两个链表上,分两种情况

①链表A与B等长,那么只需要循环一次,就能判断是否相交,相交就是交点,不相交就是null

②链表A与B不等长,那其实就是一个大小圈的问题,最后要的是pA与pB对于链表末尾的相对位置一致,最终的效果类似于方法一中的让长的先走几步。

那么这个是怎么解决这个问题的呢,就是遍历两次。假设lenA>lenB,那么A第一次循环跑的是大圈,第二次让它走B的链表,也就是跑小圈,B的指针同理,反着来,主打一个雨露均沾。

两个指针第二圈循环的过程结束两个指针的移动距离就都是lenA+lenB

 

/**
 * 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;
        //简单明了,但是相当不好想
        //当不相交的时候,pA和pB两次循环后都会变为null,没问题
        /**当相交时,其实核心思想就是让短的那个链表的指针去跑一下长的那里,让上一次跑长的来跑短的这里,这样两圈下来两个链表的指针总移动位数是一样的
        所以当第二次循环是,如果两个链表有相交的位置,他们就会在第二次循环时候相遇,如果没有,那结束第二次循环后两个都为null,也会停止,太妙了
        核心思想就是先跑长还是先跑短的问题。
        **/
        
        while(pA!=pB){
            pA = pA == null? headB:pA.next;
            pB = pB == null?headA:pB.next;
        }
        return pA;

    }
}

要点总结与心得

1、链表相交比的是指针相等

2、遇到两个长度不等需要讨论的时候,不用讨论,强行让你想代表长的那个成为长的就行了,反正只是个工具

3、双指针太精彩了,数学问题,A+B = B+A

标签:ListNode,int,随想录,相交,next,链表,curB,curA
From: https://blog.csdn.net/Griezmann_7/article/details/143109388

相关文章

  • 单链表的学习和总结
    单链表的学习和总结1.1 反转链表1.1.1 记录leetcode的题目206.反转链表92.反转链表II25.K个一组翻转链表1.1.2整理总结1.记录链表翻转的几种方法:目前我认为“头插法”更好理解https://leetcode.cn/problems/reverse-linked-list/solutions/2948411/dan-lian-......
  • 代码随想录算法训练营第八天|leetcode344.反转字符串、leetcode541. 反转字符串II、卡
    1leetcode344.反转字符串题目链接:344.反转字符串-力扣(LeetCode)文章链接:代码随想录视频链接:字符串基础操作!|LeetCode:344.反转字符串_哔哩哔哩_bilibili自己的思路:直接使用python的内置函数reverse进行一个操作1.1自己的代码1.1.1python的内置函数classSolution:......
  • 刚刚学了链表感觉好难(||^||)
    理念听得差不多明白了,但实现起来感觉好难,老师在上面写代码的时候一蹴而就,我自己尝试的时候一窍不通,下课花了好久才写出差不多的代码,大家有什么好方法吗?球球了(>_<)附上了写的链表代码,也欢迎大家提改进建议#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdli......
  • 代码随想录算法训练营day22和day23 | 77. 组合 216.组合总和III 17.电话号码的字母
    学习资料:https://programmercarl.com/回溯算法理论基础.html回溯法backtracking:for循环控制递归数量,暴力搜索:组合、切割、子集、排列、棋盘今天学了组合和切割可以画个N叉树的图来帮助理解回溯过程组合又包括1.单个数组(要加startIndex参数)或多个数组;2.数组内有无重复元素;3.数......
  • 【快慢指针】LeetCode 143. 重排链表
    题解用快慢指针先找到中间结点,然后断开前后两条链,用头插法的思路逆转后面那条链,最后两条链依次从前往后遍历插入即可。参考代码/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val(0),next(nul......
  • 代码随想录算法训练营 | 图论理论基础,98. 所有可达路径
    图论理论基础1.图的种类:有向图,无向图,加权有向图,加权无向图;2.度:无向图中有几条边连接该节点,该节点就有几度,在有向图中,每个节点有出度和入度;出度:从该节点出发的边的个数;入度:指向该节点边的个数;3.连通图:在无向图中,任何两个节点都是可以到达的;强连通图:在有向图中,任何两个节点是可以......
  • 数据结构 链表 C语言
    数据结构第二章的链表//线性表的链式存储#include<stdlib.h>#include<stdio.h>typedefintElemType;typedefstructnode{ElemTypedata;structnode*next;}Node,*LinkList;//初始化空的单链表voidInitList(LinkList*L){*L=(LinkLis......
  • 奇偶序号分割单链表(C语言)
    算法思想:要想将单链表L按照奇偶序号分割为两个单链表A(奇),B(偶),我们便可以定义一个变量来记录当前遍历的结点序号的奇偶,两个指针ra,rb,ra负责将奇数位置结点赋到A中,rb同理核心代码:voiddevide(LinkListL,LinkListA,LinkListB){intindex=1;LNode*p=L->next;......
  • 代码随想录算法训练营Day42 | 完全背包理论基础、518.零钱兑换II、377. 组合总和 Ⅳ、
    目录完全背包理论基础518.零钱兑换II377.组合总和Ⅳ卡玛网57.爬楼梯(进阶版)完全背包理论基础题目52.携带研究材料(第七期模拟笔试)题目描述:小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间......
  • 代码随想录算法训练营第七天|leetcode454.四数相加II、leetcode383. 赎金信 、leetcod
    1leetcode454.四数相加II题目链接:454.四数相加II-力扣(LeetCode)文章链接:代码随想录视频链接:学透哈希表,map使用有技巧!LeetCode:454.四数相加II_哔哩哔哩_bilibili自己的思路:第一反应就是暴力搜索,一层一层for循环来完成,就是会超时1.1自己的代码纯纯暴力搜索classSolutio......