[LeetCode]第二十七题 :两个链表交叉

题目描述:

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

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

begin to intersect at node c1.

Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns. 
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

题目解释:

写一个程序找到两个单链表交叉节点的起始位置。

注意:

1.如果两个链表没有交叉,返回null

2.在函数返回后,链表必须保持原有结构

3.你可以假设在链表中没有循环

4.你的代码最好是O(n)的时间复杂度和O(1)的空间复杂度

题目解法:

1.我的解法。两个链表交叉,那么它们后面的节点是一样的,那么就只需要从后面往前遍历即可。想要从后往前遍历,就需要把链表转换成数组,所以建立队列listA和listB;为了不破环原有链表,用工作指针workA和workB来遍历并加入到相应的队列中;然后从两个队列的末尾开始遍历,找到最靠前的相同节点即为两个链表交叉的位置。代码如下:

/**
 * 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) {
        if(headA == null || headB == null) return null;
        List<ListNode> listA = new ArrayList<>();
        List<ListNode> listB = new ArrayList<>();
        ListNode workA = headA;
        while(workA != null) {
            listA.add(workA);
            workA = workA.next;
        }
        ListNode workB = headB;
        while(workB != null) {
            listB.add(workB);
            workB = workB.next;
        }
        ListNode result = null;
        for(int i=0;i< listA.size();i++){
            int indexA = listA.size() - 1 - i;
            int indexB = listB.size() - 1 - i;
            if(indexB >= 0) {
                if(listA.get(indexA) == listB.get(indexB)) result = listA.get(indexA);
            } else break;
        }
        return result;
    }
}

2.我的想法,还没实现。从headA的头节点开始遍历,找headB中是否含有此节点,如果有那么该节点就交叉点,否则节点后移,直到找到交叉节点或者遍历完headA。

另外:我没想到有什么可以把时间复杂度控制在O(n)和空间复杂度控制在O(1)的代码。要么是时间复杂度大,要么是空间复杂度大。我还是太菜……

发布了61 篇原创文章 · 获赞 2 · 访问量 8735

猜你喜欢

转载自blog.csdn.net/woaily1346/article/details/81000770
今日推荐