一、定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点给定一个链表,判断链表中是否有环
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
复制代码
//思路:将链表中的节点的后继节点添加到前继节点上,时间复杂度O(n)
function reverseLinkedList (head) {
let prev = null,
cur = head
while (cur) {
[cur.next, cur, prev] = [prev, cur.next, cur]
}
return prev
}复制代码
二、链表探测环:给定一个链表,输入头节点,判断链表中是否有环
示例:
//方法1:数组判重
//思路:遍历链表,每遍历一个就把当前节点放到一个数组中(此处可以放到Set中,降低查询的时间复杂度为O(1)),
//然后每次遍历的时候判断数组中是否有该节点,有的话返回true有环,没有就返回false无环
function hasCycle (head) { let cur = head,
arr = []
while (cur) {
if (arr.includes(head)) {
return true
} else {
arr.push(cur)
cur = cur.next
}
}
return false
}
//方法2:快慢指针
//思路:在一个圆或者环里,跑得快和跑得慢的一定会相遇
//相比第一种,方法2的空间复杂度为O(1)
function hasCycle (head) {
if (!head || !head.next) {
return false
}
var slow = head,
fast = head.next
while (slow !== fast) {
if (!fast || !fast.next) {
return false
}
slow = slow.next
fast = fast.next.next
}
return true
}
复制代码
三、输入头节点,两两交换链接中的节点
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.复制代码
//思路:递归,找终点,只有一个节点或没有节点,返回此节点;
//两个连续节点,节点1和节点2交换,节点1的next指向下一对需要交互的节点的前一个节点,
//节点2的next指向节点1
function swapPairs (head) {
if (!head || !head.next) {
return head
}
let next = head.next
head.next = swapPairs(next.next)
next.next = head
return next
}复制代码