「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
定义
啥是链表??链表表示使用指针将一连串分散的内存块串联起来的数据结构。
js中没有链表的定义,也没有指针的定义,我们将指针想象成引用就可以。
常用的链表有三种:单链表,双向链表,循环链表。
具体定义我们不多赘述,网上资料很多,咱们直接做题~
如何实现一个链表
let data = [];
let next = [];
function add(cur, p, v) {
next[p] = next[cur]
next[cur] = p;
data[p] = v;
}
function main() {
const head = 100;
add(head, 1, 10)
add(1, 2, 20)
add(2, 3, 30)
add(3, 4, 40)
add(2, 5, 50)
data[head] = 1
let p = head;
while(p) {
console.log('->', data[p])
p = next[p]
}
}
main()
算法题
剑指 Offer 06. 从尾到头打印链表
题解: 最简单的办法是将链表数据以此unshift()塞入数组中。
我使用先翻转链表的方式(纯粹为了顺便试试翻转链表)
var reversePrint = function(head) {
const arr = [];
let dump = null;
let curIdx = head;
while(curIdx) {
const next = curIdx.next;
curIdx.next = dump;
dump = curIdx;
curIdx = next;
}
let idx = dump;
while(idx) {
arr.push(idx.val)
idx = idx.next;
}
return arr
};
面试题 02.02. 返回倒数第 k 个节点
题解:使用快慢指针,快指针走K个数,然后快慢指针同时出发,当快指针指向null时慢指针指向节点的值就是所求值
var kthToLast = function(head, k) {
let slow = head, fast = head;
while(k) {
fast = fast.next;
k--;
}
while(fast) {
slow = slow.next;
fast = fast.next;
}
return slow.val;
};
141. 环形链表
题解:快慢指针查找,快指针每次走两步,慢指针每次走一步,若有环,必定相交,否则会遍历完链表。
var hasCycle = function(head) {
let slow = head;
let fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) {
return true
}
}
return false
};
面试题 02.07. 链表相交
题解: 若两链表相交,A链表走完走从B链表的头节点开始走,B链表走完从A链表头开始走,必定会在相交处相遇。a+c+b = a+c+b。
若不相交,a+b = b+a,没有公共的C,两边都指向null。
循环跳出的条件是两节点相等,即相遇或不相交各走一遍a,b。
需要注意的是必须走下null节点,不然不相交的两个链表会永远不会相等,就进入死循环。
var getIntersectionNode = function(headA, headB) {
let l = headA, r = headB;
while(l !== r) {
l = l ? l.next : headB;
r = r ? r.next : headA;
}
return l;
};