两个链表的第一个公共结点

题目描述

输入两个链表,找出它们的第一个公共结点

编程思路

1.在第一个链表上顺序遍历每一个结点,每遍历到一个结点的时候,在第二个链表上顺序遍历每一个结点。如果在第二个链表上有一个结点和第一个链表上的结点一样,说明两个链表在这个结点上重合,便找到了他们的公共结点。如果,第一个链表的长得为m,第二个的为n,则时间复杂度为O(mn).
2.如果两个单向链表有公共结点,那么该结点的next也指向同一个结点,这样,从第一个公共结点开始,之后的所有节点都是重合的,而且公共结点出现在两个链表的尾部。如果从尾部开始往前比较,那么最后一个相同的结点就是我们找的结点。但是单向链表只能从头到尾顺序遍历,最后才能到尾结点,因此最后到达的尾结点要最先被比较,这就是典型的“后进先出”,因此可以用栈实现。分别把两个链表的结点放入两个栈里,这样链表的尾结点就是栈顶,接下来比较两个栈顶的结点是否相同,如果相同,则把栈顶弹出接着比较下一个栈顶,直到找到最后一个相同的结点。这这种思路的时间复杂度是O(m+n)。
3.由于两个链表的长度可能不一样,因此从头开始遍历到达尾结点的时间就不一致,因此,我们可以先遍历一遍两个链表得到他们的长度,知道哪个链表长,并且长几个结点,然后在第二次遍历时,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到的第一个相同的结点就是他们的第一个公共结点。这种思路的时间复杂度也是O(m+n),但不需要辅助栈,提高了空间效率,因此,就使用这种思路来编程。

程序代码(Java语言)

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
 		int length1 = getLength(pHead1);
        int length2 = getLength(pHead2);
        int length = 0;
        
        ListNode ListHeadLong = null;  
        ListNode ListHeadShort = null; 
        if(length2 > length1) {
            ListHeadLong = pHead2;
            ListHeadShort = pHead1;
            length = length2 - length1;
        } else {
            ListHeadLong = pHead1;
            ListHeadShort = pHead2;
            length = length1 - length2;
        }
        for(int i = 0;i < length;i++) {
            ListHeadLong = ListHeadLong.next;
        }
        while((ListHeadLong != null) && (ListHeadShort != null) && (ListHeadLong != ListHeadShort)) {
            ListHeadLong = ListHeadLong.next;
            ListHeadShort = ListHeadShort.next;
        }
        return ListHeadLong;
    }
    
    private int getLength(ListNode head) {
        int length = 0;
        ListNode node = head;
        while(node != null) {
            ++length;
            node = node.next;
        }
        return length;
    }
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值