项目地址: github.com/AlienGao/le…
2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
解题思路
两数相加结果有两种,一种小于10不需要进位,另一种大于等于10需要进位(两数相加后取首位a + b | 0)。设置一个变量(carry)来存储进位,默认为0。某一位的值其实是两个数字对应位置只和与进位相加取余的结果。再遍历个链表,将每一位相加。
var addTwoNumbers = function(l1, l2) {
let head = null, tail = null;
let carry = 0;
while (l1 || l2) {
let n1 = l1 ? l1.val : 0
let n2 = l2 ? l2.val : 0
let sum = n1 + n2 + carry
if (!head) {
head = tail = new ListNode(sum % 10)
} else {
tail.next = new ListNode(sum % 10)
tail = tail.next
}
carry = sum / 10 | 0
if (l1) {
l1 = l1.next
}
if (l2) {
l2 = l2.next
}
}
if (carry > 0) {
tail.next = new ListNode(carry)
}
return head
};
21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
解题思路
假设l1为新链表起始,将当前位与l2当前位比较,若小于l2当前位,l1指针往下走一位,再和l2比较,若大于l2,则l2走一位。
var mergeTwoLists = function(l1, l2) {
if (!l1) return l2
if (!l2) return l1
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2)
return l1
} else {
l2.next = mergeTwoLists(l2.next, l1)
return l2
}
};
141. 环形链表
给定一个链表,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 如果链表中存在环,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
解题思路
使用快慢指针,慢指针每次走一步,快指针每次走两步,若快慢指针相遇,则说明有环。若快指针指向null则遍历结束,表明没有环。
var hasCycle = function(head) {
if (!head || !head.next) return false
let slow = head
let fast = head
// 快慢指针 若相遇则表明有环
while(fast.next && fast.next.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) {
return true
}
}
return false
};
203. 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1
输出:[]
解题思路
使用迭代,若指针指向的值与整修相等,则指针向后走一位。
var removeElements = function(head, val) {
if (head === null) {
return head
}
head.next = removeElements(head.next, val)
return head.val === val ? head.next : head
};
206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
解题思路
设置一个变量prv用来存储head当前指针的值,并设置head的后一位为prv。相当于head.next -> head,则能实现反转。
var reverseList = function(head) {
let prv = null
let cur = head
while(cur) {
const next = cur.next
cur.next = prv
prv = cur
cur = next
}
return prv
};