剑指offer之两个链表的第一个公共结点

这篇博客探讨了如何解决剑指offer中的一个问题——找出两个链表的第一个公共结点。博主分享了两种解题思路,包括使用辅助栈的方法1和通过计算链表长度差的方法2,后者的时间复杂度为O(m+n)。最后,博主提到了评论区的一个高效代码,只需遍历链表总长度即可找到公共结点。
摘要由CSDN通过智能技术生成

剑指offer之两个链表的第一个公共结点

题目描述

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

解题思路

只会暴力到怀疑人生,无果。书上给出了两种思路。由于两个链表尾部是一样的,所以方法1是用两个辅助栈存放两个链表,然后最后一个值和next地址相同的结点就是第一个公共结点,时空复杂度都是O(m+n)。方法2就更妙了,先获得两个链表的长度,然后让长的先走长-短的差的步数,之后第一个值和next都相同的结点就是公共结点,时间复杂度是O(m+n)。

Code

  • 方法2
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    int GetLengthOfList(ListNode* pHead) {
        if(!pHead) return 0;
        return 1+GetLengthOfList(pHead->next);
    }
    ListNode* GetKStepList(ListNode* pHead, int kStep) {
        if(!pHead) return nullptr;
        if(kStep > 0) {
            return GetKStepList(pHead->next, kStep-1);
        }
        return pHead;
    }
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        int length1 = GetLengthOfList(pHead1), length2 = GetLengthOfList(pHead2);
        ListNode* pNode1 = pHead1, *pNode2 = pHead2;
        int difference = length1-length2;
        if(difference > 0) {
            pNode1 = GetKStepList(pHead1, difference);
        } else {
            pNode2 = GetKStepList(pHead2, -difference);
        }
        while(pNode1 && pNode2 && (pNode1->val != pNode2->val || pNode1->next != pNode2->next)) {
            pNode1 = pNode1->next;
            pNode2 = pNode2->next;
        }
        if(pNode1 && pNode2 && pNode1->val == pNode2->val && pNode1->next == pNode2->next) {
            return pNode1;
        }
        return nullptr;
    }
};
  • java
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
import java.util.LinkedList;
public class Solution {
    public LinkedList<ListNode> GetLinkedList(ListNode pHead) {
        LinkedList<ListNode> list = new LinkedList<ListNode>();
        while(pHead != null) {
            list.add(pHead);
            pHead = pHead.next;
        }
        return list;
    }
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode result = null;
        LinkedList<ListNode> list1 = GetLinkedList(pHead1);
        LinkedList<ListNode> list2 = GetLinkedList(pHead2);
        while(!list1.isEmpty() && !list2.isEmpty()) {
            ListNode temp1 = list1.removeLast();
            ListNode temp2 = list2.removeLast();
            if(temp1 != temp2) {
                break;
            }
            result = temp1;
        }
        return result;
    }
}
  • 看完评论区被一个代码惊艳到了,只要遍历两个链表和的长度就可以找到第一个公共结点
链接:https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46
来源:牛客网

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
        ListNode *p1 = pHead1;
        ListNode *p2 = pHead2;
        while(p1!=p2){
            p1 = (p1==NULL ? pHead2 : p1->next);
            p2 = (p2==NULL ? pHead1 : p2->next);
        }
        return p1;
    }
};

总结

看评论区代码,公共结点的比较可以直接用指针判等比较。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值