开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
引言
算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。
题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例 2:
输入: head = [1,2]
输出: [2,1]
示例 3:
输入: head = []
输出: []
分析
根据题目的分析,我们如何快速的完成链表的反转?通过对链表特点的回忆,我们可以使用头插法在遍历链表的过程中进行反转。
- 定义一个虚拟头节点
- 从真正的第一个节点开始遍历
- 遍历的同时插入链接到虚拟头节点
- 最后返回虚拟节点的下一个节点作为真正的头结点
解答
var permute = function(nums) {
let path = []
let res = []
const main = used => {
if(path.length === nums.length) res.push([...path])
for(let i=0;i<nums.length;i++) {
if(used[i]) continue
used[i] = true
path.push(nums[i])
main(used)
used[i] = false
path.pop()
}
}
main()
return res
};
整体的设计是基于单链表的头插法完成的,在遍历链表的同时可以持续的将链表插入到头部分,整体的设计十分的巧妙和简单。算法的时间复杂度是o(n),空间复杂度是o(n)。
总结
通过对链表的反转的讲解,大家学到了进行问题的解决。通过头插法算法巧妙计算可以优雅的在低时间和空间复杂度下完成任务。