题目描述:
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)的代码。要么是时间复杂度大,要么是空间复杂度大。我还是太菜……