leetcode160-相交链表

原题

编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:

leetcode160-相交链表

在节点 c1 开始相交。

示例 1:

leetcode160-相交链表

输入: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出: Reference of the node with value = 8
输入解释: 相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

leetcode160-相交链表

输入: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出: Reference of the node with value = 2
输入解释: 相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

leetcode160-相交链表

输入: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出: null
输入解释: 从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

解法

思想

  1. HashSet
    依次将获取到的链表元素插入一个HashSet中,返回第一个重复的节点。
  2. 双指针
    两个指针从头走到尾的路径长度之差就是两条路径相交点前的长度之差,获取了这个差之后就可以路径短的让路径长的先走几步,然后同时出发,在相交点相遇。

代码

HashSet:

/**
 * 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) {
        if(headA==null || headB==null) return null;
        Set<ListNode> set = new HashSet<ListNode>();
        ListNode curA = headA;
        ListNode curB = headB;
        while(curA!=null){
            set.add(curA);
            curA = curA.next;
        }
        while(curB!=null){
            if(set.contains(curB))
                return curB;
            set.add(curB);
            curB = curB.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) {
        if(headA == null || headB == null) return null;
        if(headA == headB) return headA;
        ListNode curA = headA;
        ListNode curB = headB;

        int countA = 0;
        int countB = 0;
        //两个指针先一起走一遍
        while(curA!=curB && (curA.next!=null || curB.next!=null)){
            if(curA.next!=null){
                curA = curA.next;
                countA++;
            }
            if(curB.next!=null){
                curB = curB.next;
                countB++;
            }
        }
        if(curA != curB) return null;
        //获取两条路径的长度只差
        int step;
        ListNode longer;
        ListNode near;
        if(countA>=countB){
            step = countA-countB;
            longer = headA;
            near = headB;
        }else{
            step = countB-countA;
            longer = headB;
            near = headA;
        }
        //近的让远的先走
        while(longer != near){
            longer = longer.next;
            if(step==0)
                near = near.next;
            else
                step --;
        }
        return longer;
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode160-%e7%9b%b8%e4%ba%a4%e9%93%be%e8%a1%a8/

(0)
彭晨涛彭晨涛管理者
上一篇 2019年12月13日 18:05
下一篇 2019年12月15日

相关推荐

  • leetcode18-四数之和

    原题 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 ta…

    算法 2020年5月5日
    0120
  • leetcode31-下一个排列

    原题 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1…

    算法 2022年4月13日
    02593
  • 程序员面试金典01.06-字符串压缩

    原题(来源Leetcode) 字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字…

    算法 2020年3月16日
    0240
  • leetcode4-寻找两个有序数组的中位数

    这道题我没想出符合条件的思路 原题 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m…

    算法 2020年1月9日
    0620
  • leetcode210-课程表II

    原题 现在你总共有 n 门课需要选,记为 0 到 n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0…

    算法 2020年5月17日
    0130
  • leetcode11-盛最多水的容器

    原题 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i,…

    2020年2月27日
    0250
  • 剑指offer35-复杂链表的复制

    原题(来源Leetcode) 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random …

    2020年6月13日
    0110
  • 剑指offer57-和为s的连续正数序列

    原题(来源Leetcode) 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。 序列内的数字由小到大排列,不同序列按照首个数字从小到…

    算法 2020年3月6日
    050
  • leetcode5-最长回文子串

    原题 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有…

    算法 2020年2月20日
    0110
  • 剑指offer51-数组中的逆序对

    原题(来源Leetcode) 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 示例 1: 输入: [7…

    算法 2020年4月24日
    0400

发表回复

登录后才能评论