36.两个链表的第一个公共节点

题目描述

输入两个链表,找出它们的第一个公共结点。
1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点。
这种算法时间复杂度为O(m+n),但是空间复杂度也是O(m+n),相当于是空间换时间
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
import java.util.*;
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        Stack<ListNode> s1=new Stack<ListNode>();
        Stack<ListNode> s2=new Stack<ListNode>();
        
        while(pHead1!=null){
            s1.add(pHead1);
            pHead1=pHead1.next;
        }
        
        while(pHead2!=null){
            s2.add(pHead2);
            pHead2=pHead2.next;
        }
        
        ListNode foundNode =null;
        ListNode node =null;
         while(!s1.isEmpty() && !s2.isEmpty()){
            node=s1.pop();
            if(node==s2.pop())
                foundNode =node;
            else 
                return foundNode;
        }
        return foundNode;
    }
}
View Code

2.利用HashSet中元素不能重复的原理,首先遍历一个链表进行存放,然后遍历另外一个链表,找到第一个与Set中元素相同的节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
            ListNode current1 = pHead1;
            ListNode current2 = pHead2;
     
     
            HashSet <ListNode> hashSet = new HashSet<ListNode>();
            while (current1 != null) {
                hashSet.add(current1);
                current1 = current1.next;
            }
            while (current2 != null) {
                if (hashSet.contains(current2))
                    return current2;
                current2 = current2.next;
            }
     
            return null;
     
        }
View Code

 

3.首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。第二次遍历的时候,在较长的链表上线走若干步,接着同时在两个链表上遍历,找到的第一个相同的节点就是它们的第一个公共节点。

链接:https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46
来源:牛客网

public ListNode FindFirstCommonNodeII(ListNode pHead1, ListNode pHead2) {
        ListNode current1 = pHead1;// 链表1
        ListNode current2 = pHead2;// 链表2
        if (pHead1 == null || pHead2 == null)
            return null;
        int length1 = getLength(current1);
        int length2 = getLength(current2);
        // 两连表的长度差
         
        // 如果链表1的长度大于链表2的长度
        if (length1 >= length2) {
            int len = length1 - length2;
            // 先遍历链表1,遍历的长度就是两链表的长度差
            while (len > 0) {
                current1 = current1.next;
                len--;
            }
 
        }
        // 如果链表2的长度大于链表1的长度
        else if (length1 < length2) {
            int len = length2 - length1;
            // 先遍历链表1,遍历的长度就是两链表的长度差
            while (len > 0) {
                current2 = current2.next;
                len--;
            }
 
        }
        //开始齐头并进,直到找到第一个公共结点
        while(current1!=current2){
            current1=current1.next;
            current2=current2.next;
        }
        return current1;
 
    }
 
    // 求指定链表的长度
    public static int getLength(ListNode pHead) {
        int length = 0;
 
        ListNode current = pHead;
        while (current != null) {
            length++;
            current = current.next;
        }
        return length;
    }
View Code

相关文章: