输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围:
要求:空间复杂度 ,时间复杂度
要求:空间复杂度 ,时间复杂度
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。
输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,第三段是第一个链表和第二个链表的公共部分。 后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2。
返回传入的pHead1和pHead2的第一个公共结点,后台会打印以该节点为头节点的链表。
{1,2,3},{4,5},{6,7}
{6,7}
第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分 这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的
{1},{2,3},{}
{}
2个链表没有公共节点 ,返回null,后台打印{}
/*function ListNode(x){ this.val = x; this.next = null; }*/ function FindFirstCommonNode(pHead1, pHead2) { // write code here let set1 = new Set(); while(pHead1){ set1.add(pHead1); pHead1 = pHead1.next; } while(pHead2){ if(set1.has(pHead2)){ return pHead2; } pHead2 = pHead2.next; } return null; } module.exports = { FindFirstCommonNode : FindFirstCommonNode };
function FindFirstCommonNode(pHead1, pHead2) { let cur1 = pHead1 let cur2 = pHead2 let myset = new Set() while(cur1!==null){ if(!myset.has(cur1)){ myset.add(cur1) cur1 = cur1.next }else{ return cur1 } } while(cur2!==null){ if(!myset.has(cur2)){ myset.add(cur2) cur2 = cur2.next }else{ return cur2 } } return null }使用集合做的巧妙解法
function FindFirstCommonNode(pHead11, pHead22) { // write code here let pHead1=pHead11; let pHead2=pHead22; while(pHead1!=pHead2){ pHead1=pHead1==null?pHead22:pHead1.next; pHead2=pHead2==null?pHead11:pHead2.next; } return pHead2; } module.exports = { FindFirstCommonNode : FindFirstCommonNode };
/*function ListNode(x){ this.val = x; this.next = null; }*/ function FindFirstCommonNode(pHead1, pHead2) { let list = {}; let path = 1; while(pHead1){ list[pHead1.val] = path; pHead1 = pHead1.next; path ++; } let min = path; let result = null; while(pHead2){ if(list[pHead2.val] && list[pHead2.val] <= min){ result = pHead2; min = list[pHead2.val]; } pHead2 = pHead2.next; } return result; }
/*function ListNode(x){ this.val = x; this.next = null; }*/ /** * 我的解题思路: * 1.emmmm,这个问题之前面头条的时候被问到过,没答出来的但是面试官给讲了思路哈哈哈,这次做出来了 * 2.先让两个链表同时开始遍历,直到较短的那个链表所有节点都被遍历 * 3.让较长的链表从头开始遍历,直到第二步中剩余部分遍历完成,此时长链表剩余部分与短链表长度相同 * 4.直接顺序遍历两个链表,找到节点值相同的节点并返回即可,若找不到相同节点,返回null * * @param {*} pHead1 * @param {*} pHead2 */ function FindFirstCommonNode(pHead1, pHead2) { // write code here let temp1 = pHead1; let temp2 = pHead2; while (temp1 && temp2) { temp1 = temp1.next; temp2 = temp2.next; } while (temp1) { pHead1 = pHead1.next; temp1 = temp1.next; } while (temp2) { pHead2 = pHead2.next; temp2 = temp2.next; } while (pHead1 && pHead2 && pHead1.val !== pHead2.val) { pHead1 = pHead1.next; pHead2 = pHead2.next; } return pHead1; } /** * 评论区TOP的解题思路: * 1.思路还是那个思路,跟我的类似,只不过它采取了更简洁的写法 * 2.遍历两个链表,直到找到相同的节点,结束遍历(在JS中无法直接比较节点,这里采用JSON.stringify转成字符串再比较的方式处理) * 3.若未找到相同节点,则继续遍历,如果发现短链表遍历结束,那么将短链表指向长链表的头部继续进行遍历,此时遍历的部分为全新的长链表和剩余部分的长链表 * 4.在之前长链表剩余部分遍历完成之后,另一个长链表已经走出了多出的长度,此时让为空的长链表指向短链表的头部,这样得到的两个链表长度就一致了 * 5.继续进行遍历,直到找到相同节点即可 * * @param {*} pHead1 * @param {*} pHead2 */ function topFindFirstCommonNode(pHead1, pHead2) { // write code here let temp1 = pHead1; let temp2 = pHead2; while (JSON.stringify(temp1) !== JSON.stringify(temp2)) { temp1 = temp1 ? temp1.next : pHead2; temp2 = temp2 ? temp2.next : pHead1; } return temp1; }
function ListNode(x){ this.val = x; this.next = null; } function FindFirstCommonNode(pHead1, pHead2) { // write code here var arr1 = []; var curr1 = pHead1; var curr2 = pHead2; while(curr1 != null){ arr1.push(curr1.val); curr1 = curr1.next; } while(curr2 != null){ if(arr1.includes(curr2.val)) return curr2; curr2 = curr2.next; } } module.exports = { FindFirstCommonNode : FindFirstCommonNode };
function ListNode(x){ this.val = x; this.next = null; } function FindFirstCommonNode(pHead1, pHead2) { // 让链表成环 let pNode2 = pHead2; while (pNode2.next) { pNode2 = pNode2.next; } pNode2.next = pHead2; // 快慢针判断成环链表的环起点 let fast = pHead1; let slow = pHead1; while (fast && fast.next) { fast = fast.next.next; slow = slow.next; if (fast == slow) { fast = pHead1; while (fast != slow) { fast = fast.next; slow = slow.next; } return fast; } } return null; }
/*function ListNode(x){ this.val = x; this.next = null; }*/ function FindFirstCommonNode(pHead1, pHead2) { // write code here let len1 = 0; let len2 = 0; let curr1 = pHead1; let curr2 = pHead2; while(curr1){ len1 ++; curr1 = curr1.next; } while(curr2){ len2 ++; curr2 = curr2.next; } curr1 = pHead1; curr2 = pHead2; if(len1 > len2){ let diff = len1 - len2; while(diff--){ curr1 = curr1.next; } }else{ let diff = len2 - len1; while(diff--){ curr2 = curr2.next; } } while(curr1 !== curr2){ curr1 = curr1.next; curr2 = curr2.next; } return curr1; }
function ListNode(x) { this.val = x; this.next = null; } function FindFirstCommonNode(pHead1, pHead2) { // write code here let myMap = new Map(); let p = pHead1; let q = pHead2; while (p) { myMap.set(p, 1); p = p.next; } while (q) { if (myMap.has(q)) { return q; } q = q.next; } return; } var l1 = new ListNode(1); var l2 = new ListNode(2); var l3 = new ListNode(3); var l4 = new ListNode(4); var l5 = new ListNode(5); l1.next = l2; l2.next = l3; l3.next = l4; l4.next = l5; var l6 = new ListNode(6); var l7 = new ListNode(7); var l8 = new ListNode(8); var l9 = new ListNode(9); l6.next = l7; l7.next = l8; l8.next = l3; let res = FindFirstCommonNode(l1, l6); console.log(res);
function ListNode(x){ return { val:x, next:null } } function FindFirstCommonNode(pHead1, pHead2) { // write code here while(pHead1) { pHead1.tag = true pHead1 = pHead1.next } while(pHead2) { if(pHead2.tag) { pHead2.tag = undefined return pHead2 } else { pHead2 = pHead2.next } } return null }
function FindFirstCommonNode(pHead1, pHead2) { if (!pHead1 || !pHead2) { return null; } // 获取链表长度 let length1 = getLength(pHead1); let length2 = getLength(pHead2); // 长链表先行 let lang, short, interval; if (length1 > length2) { lang = pHead1; short = pHead2; interval = length1 - length2; } else { lang = pHead2; short = pHead1; interval = length2 - length1; } while (interval--) { lang = lang.next; } // 找相同节点 while (lang) { if (lang === short) { return lang; } lang = lang.next; short = short.next; } return null; } function getLength(head) { let current = head; let result = 0; while (current) { result++; current = current.next; } return result; }
/*function ListNode(x){ this.val = x; this.next = null; }*/ function FindFirstCommonNode(pHead1, pHead2) { // write code here var len1 = 0; //记录pHead1的长度 var len2 = 0; //记录pHead2的长度 var p1=pHead1; //指向pHead1的首节点 var p2=pHead2; //指向pHead2的首节点 //遍历链表pHead1,记录其长度len1 while(p1 != null){ len1++; p1=p1.next; } //遍历链表pHead2,记录其长度len2 while(p2 != null){ len2++; p2=p2.next; } //比较len1和len2大小,对于更长的链表,先指向其第|len1-len2|个节点 p1=pHead1; p2=pHead2; if(len1 > len2){ var num = len1-len2; for(var i=0;i<num; i++){ p1=p1.next; } } if(len1 < len2){ var num = len2-len1; for(var i=0;i<num; i++){ p2=p2.next; } } //以当前p1,p2所指向的节点为基础,依次比较其指向的节点是否相同,若不相同,则指向next节点;若相同,则该节点为第一个公共节点,返回当前节点。 while(p1 != null){ if(p1 == p2){ return p1; } p1=p1.next; p2=p2.next; } return false; }