找两个单链表的交叉节点

解法一
  • 着重考虑两个单链表长度不相同的情况,这时需要计算两个单链表的长度并转化成相同长度的单链表
  • 代码
/**
 * 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 A = new ListNode(0);
        ListNode B = new ListNode(0);
        A = headA;
        B = headB;
        int lengthA = length(A);
        int lengthB = length(B);
        System.out.println(lengthA + "\t" + lengthB);
        A = lengthA >= lengthB ? headA : headB;
        B = lengthA >= lengthB ? headB : headA;
        int n = Math.abs(lengthA - lengthB);
        while (n > 0) {
            A = A.next;
            n -= 1;
        }
        if (A == B) return A;
        while (A != null && B != null) {

            if (A.next == B.next) return A.next;
            A = A.next;
            B = B.next;
        }
        return null;
    }
    public int length(ListNode l) {
        int len = 0;
        while (l != null) {
            len += 1;
            l = l.next;
        }
        return len;
    }
}
  • 思路
    • 将两个单链表的长度均求出来,并计算两个长度的差
    • 始终将A指向较长的单链表,B指向较短的单链表,将A的指向改变长度,变成与B相同的单链表,因为如果两个链表之间的有交叉的话,两个链表的尾部应该是对齐的,所以长度的差异从头部去掉,就可以逐个节点进行比较了

解法二
  • 将两个单链表进行分类,分别分成长度不相同和长度相同的两大类,与解法一不同的是,对待长度不相同的这种情况,并没有进行长度差的计算,而是利用两个指针分别遍历两个链表:即指针A遍历链表l1和链表l2,指针B遍历链表l2和链表l1。这样当两个指针遍历最长的那个链表长度后,两个指针所指向的节点位置是相对应的
    • 图示
      图解
      • 图中的红色代表A指针的遍历过程,蓝色代表B指针的遍历过程,发现在遍历八次后,第九次两个指针的所指位置相同
  • 代码
 /**
 * 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 a = headA;
        ListNode b = headB;
        while (a != b) {
            a = a == null ? headB : a.next;
            b = b == null ? headA : b.next;
        }
        return a;
    }
}
  • 单链表长度相同的话,一次遍历就可以结束,如果不相同,需要二次遍历,如图所示,但是最多在第二次遍历的时候结束

解法四
  • 思路
    • 采用Java中自带的数据结构HashSet来实现,set中不能包含相同的值,所以如果向set中添加节点失败,那么这个节点就是交叉节点。
  /**
 * 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) {
        HashSet<ListNode> set = new HashSet<ListNode>();
        while (headA != null) {
            set.add(headA);
            headA = headA.next;
        }
        while (headB != null) {
            if (!set.add(headB)) return headB;
            headB = headB.next;
        }
        return null;
    }
}
  • 运行的速度都没有上面的两种方法好
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值