这是我参与更文挑战的第 10 天,活动详情查看 更文挑战
这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
116. 相交链表 (intersection-of-two-linked-lists)
标签
- 链表
- 简单
题目
这里不贴题了,leetcode打开就行,题目大意:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点
。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:listA = [4,1,8,4,5], listB = [5,0,1,8,4,5]
输出:Intersected at '8'
解释:相交节点的值为 8
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4]
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
基本思路
- 用指针 PA 指向 A 链表,指针 PB 指向 B 链表
A 链表 (ABCDEFG)
headA
PA
|
A -> B -> C -> D -> E -> F -> G -> null
|
X -> Y -> Z
|
PB
headB
B 链表 (XYZEFG)
交点在 `E` 点
- PA, PB 指针依次往后走,
- PA 假设
A->E(交点)
距离为l1
(4步) - PB 假设
X->E(交点)
距离为l2
(3步) - 由交点到结尾 距离为
l3
(3步)
- PA 假设
// [A -> E l1=4步] [E -> null l3=3步]
(A) -> B -> C -> D -> (E) -> F -> (G) -> null
^
|
(X) -> Y -> Z
// [X -> E l2=3步]
就本例而言,A 链长,A的路径是 A -> E -> 尾部,然后到 B的头 -> X -> E
, 走过的路径就是 l1 -> l3 -> l2
,B链是 X -> E -> null -> A -> E
,路径是 l2 -> l3 -> l1
,如果有交点的话,那么此时会走到一起。
所以做法就是
- 如果 PA 到了末尾,则
PA = headB
继续遍历 - 如果 PB 到了末尾,则
PB = headA
继续遍历
- 如果上面两个指针经过遍历能走到一起,说明是有交点,都各自走到最后为
null
则没有交点返回null
, 此时其实就是两个指针交换都会走到最后,走过的路径就都是(长链 + 短链)
的和, 就是他走过的路,你再走一遍,都走到对方的 null, 那么两人走过路径就是两段路的和
写法实现
var getIntersectionNode = function(headA, headB) {
if (!headA || !headB) {
return null
}
let [PA, PB] = [headA, headB]
// 要么有交点,要么都是 null
while (PA !== PB) {
PA = PA === null ? headB : PA.next;
PB = PB === null ? headA : PB.next;
}
return PA
};
117. 最长回文子串 (longest-palindromic-substring)
标签
- 字符串
- 中等
题目
这里不贴题了,leetcode打开就行,题目大意:
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
基本思路
遍历每一个位置,使其作为『中心』并分奇偶讨论
奇偶讨论
- 回文子串长度为奇数(如
aba
,中心是b
) - 回文子串长度为偶数(如
cbbd
,中心是b,b
)
写法实现
function longestPalindrome(s) {
let res = ''
// 传入中心(左右)坐标,返回以s[l]和s[r]为中心的最长回文串
const longestPS = (l, r) => {
// 左右不能超边界, 相同情况向两边扩散
while (l >= 0 && r < s.length && s[l] === s[r]) {
l--;
r++;
}
return s.substring(l + 1, r);
}
// 遍历每一个位置,使其作为『中心』并分奇偶讨论
for (let i = 0; i < s.length; i++) {
// 奇数中心最长串, i 作为坐标,技术中间是一个坐标
let oddStr = longestPS(i, i)
// 偶数中心最长串
let evenStr = longestPS(i, i+1)
// 找出最长回文即可
if (oddStr.length > evenStr.length) {
// 奇数的大
res = res.length > oddStr.length ? res : oddStr
} else {
res = res.length > evenStr.length ? res : evenStr
}
}
return res
}
console.log(longestPalindrome('babad')) // aba
console.log(longestPalindrome('cbbd')) // bb
另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友
Or 搜索我的微信号infinity_9368
,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文
,验证消息请发给我
presious tower shock the rever monster
,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧