1、合并两个有序链表
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
const prehead = new ListNode(-1); //创建虚拟表头
let prev = prehead; //创建指针prev指向这个表头
while (l1 != null && l2 != null) { //l1,l2都为空说明合并完毕
if (l1.val <= l2.val) { //如果l1的值小于l2
prev.next = l1; //l1接在创建的虚拟表头后面
l1 = l1.next; //l1的指针向后移
} else {
prev.next = l2; //l2接在创建的虚拟表头后面
l2 = l2.next; //l2的指针向后移
}
prev = prev.next; //创建的虚拟表头的指针向后移
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev.next = l1 === null ? l2 : l1;
return prehead.next; //得到最终合并的链表
};
2、回文链表
示例 1:
输入:head = [1,2,2,1] 输出:true
示例 2:
输入:head = [1,2] 输出:false
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
const vals = []; //创建新数组
while (head !== null) { //直到链表遍历完成
vals.push(head.val); //把链表的值加入到数组中
head = head.next; //取得链表的下一个值
}
for (let i = 0, j = vals.length - 1; i < j; ++i, --j) { //类似双指针,第一位和最后一位比,以此类推
if (vals[i] !== vals[j]) { //如果不相等返回false
return false;
}
}
return true; //走到这一步说明都相等满足条件,返回true
};
3、环形链表
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function (head) { //利用json.stringfy的特性,JSON.stringify()方法在对象出现循环引用的时候会报错
try {
JSON.stringify(head)
} catch{
return true //抓到错误,说明有循环,返回true
}
return false //没错误,说明没有,返回false
};
var hasCycle = (head) => {
let map = new Map(); //创建hash表
while (head) { //遍历链表
if (map.has(head)) return true; //链表中存在返回true
map.set(head, true); // 存的是节点的地址引用,而不是节点值
head = head.next; //链表往后移
}
return false; //能执行到这一步说明没有,返回false
};