LeetCode笔记——160相交链表 &&剑指52

题目:

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

 

例如,下面的两个链表

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

 

注意:

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

思路:看到这个题并没有什么思路。。。。。。链表的题总是不会。。。。。。。然后就网上找了大神的代码,还有leetcode上提交最快的代码。下面就先看懂这两个代码吧。。。

思路1 :最快的代码

这个代码首先用来两个while循环到达链表末尾并得到链表中的节点数。如果链表相交最后一个节点一定是相等的,先判断最后一个节点。之后就类似将两个链表以链表结尾对齐,依次判断节点是否相等。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) return null;
        ListNode p = headA;
        ListNode q = headB;
        int pn = 1;
        int qn = 1;
        while(p.next != null){
            pn++;
            p = p.next;
        }
        while(q.next != null){
            qn++;
            q = q.next;
        }
        if(p != q) return null;
        //reset p,q
        p = headA;
        q = headB;
        if(pn > qn){
            int d = pn - qn;
            while(d > 0 && p != null){
                p = p.next;
                d--;
            }
        }else if(pn < qn){
            int d = qn - pn;
            while (d >0 && q != null){
                q = q.next;
                d--;
            }
        }
        while(p != null && q != null){
            if(p == q) return q;
            p = p.next;
            q = q.next;
        }
        return null;
    }
}

思路2:大神们的代码

两个链表的长度如果相等直接比较找相等;如果长度不同,将短链表补在长链表后面,短链表补在长链表后面。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
       if (headA == null || headB == null) return null;
        ListNode listA = headA, listB = headB;
        while (listA != null && listB != null) {
            if (listA == listB) return listA;
            listA = listA.next;
            listB = listB.next;
            if (listA == listB) return listA;
            if (listA == null) listA = headB;
            if (listB == null) listB = headA;
        }
        return listA;
    }
}

注意:

(1)return可以用来退出整个函数,当然也可以退出整个循环

(2)listA == listB链表中这两个节点相等应该指的是指向的是同一个内存区域.==比较的是两个对象的内存地址是否相等。

这个题目是剑指的第52题:两个链表的第一个公共节点,以下是剑指中的思路:首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第二次遍历的时候,在较长的链表上先走几若干步。接着同时在两个链表上遍历,找到的第一个节点就是它们的第一个公共节点。以下这个代码其实并不需要遍历链表的长度,通过以下黑体的部分代码可以实现在长链表上先走几步的想法。

这个题字节和百度的出现了两次。

代码如下:

public class Solution {
   
       public ListNode getIntersectionNode(ListNode pHead1, ListNode pHead2) {
       ListNode p1 = pHead1;
           ListNode p2 = pHead2;
while (p1 != p2){
p1 = (p1 != null ? p1.next : pHead2);
p2 = (p2 != null ? p2.next : pHead1);
}
return p1;
}
    
}

你可能感兴趣的:(LeetCode笔记,剑指)