点击查看剑指Offer全解【Java & Golang】实现
题目描述
给定两个链表,寻找两个链表的第一个公共节点。
思路
第一种思路,创建一个HashSet,先遍历一遍链表一,并且存储每个节点在HashSet中,接着遍历链表二,如果出现了HashSet中的节点,那么该节点就是第一个公共节点。这种方法的时间复杂度为O(n + k),空间复杂度为O(n),n是第一条链表节点数,k是第二条链表节点数。
第二种思路,两个链表中,我们可以先遍历一次得到它们的长度分别为5 和4, 也就是较长的链表与较短的链表相比多一个结点。第二次先在长的链表上走1 步,到达结点2。接下来分别从结点2 和结点4 出发同时遍历两个结点, 直到找到它们第一个相同的结点6,这就是我们想要的结果。这种做法的时间复杂度也是O(n + k),但是不需要额外的空间复杂度,为O(1)。
Java第一种思路实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.HashSet;
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
HashSet<ListNode> set = new HashSet<>();
while (pHead1 != null) {
set.add(pHead1);
pHead1 = pHead1.next;
}
while (pHead2 != null) {
if (set.contains(pHead2)) {
return pHead2;
}
pHead2 = pHead2.next;
}
return null;
}
}
Java第二种思路实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.HashSet;
public class Solution {
public ListNode FindFirstCommonNode(ListNode head1, ListNode head2) {
int length1 = getListLength(head1);
int length2 = getListLength(head2);
int step = length1 - length2;
if (step > 0) {
for (int i = 0; i < step; i++) {
head1 = head1.next;
}
} else {
for (int i = 0; i < -step; i++) {
head2 = head2.next;
}
}
while (head1 != null && head2 != null) {
if (head1 == head2) {
return head1;
}
head1 = head1.next;
head2 = head2.next;
}
return null;
}
private static int getListLength(ListNode head) {
int result = 0;
while (head != null) {
result++;
head = head.next;
}
return result;
}
}
Golang第一种思路实现
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
set := make(map[*ListNode]string)
for headA != nil {
// 使用map充当set
set[headA] = "PRESENT"
headA = headA.Next
}
for headB != nil {
if _, ok := set[headB]; ok{
return headB
}
headB = headB.Next
}
return nil
}
Golang第二种思路实现
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
lenA := getLength(headA)
lenB := getLength(headB)
step := lenA - lenB
if step > 0 {
for i := 0; i < step; i++ {
headA = headA.Next
}
} else {
for i := 0; i < -step; i++ {
headB = headB.Next
}
}
for headA != nil && headB != nil {
if headA == headB {
return headA
}
headA = headA.Next
headB = headB.Next
}
return nil
}
func getLength(head *ListNode) int {
cur := head
count := 0
for cur != nil {
count++
cur = cur.Next
}
return count
}