开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情
引言
算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。
题目描述
给你链表的头节点 head ,每 k **个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k **的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]
示例 2:
输入: head = [1,2,3,4,5], k = 3
输出: [3,2,1,4,5]
提示:
- 链表中的节点数目为
n 1 <= k <= n <= 50000 <= Node.val <= 1000
进阶: 你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?
分析
根据题目的分析,我们如何设计求k个链表翻转?根据链表的不连续空间特点,我们可以逐个的链表拼接完成。 。
- 首先定义空的头节点,省去判断空
- 按照每k个节点完成一次头插法拼接
- 当拼接到末尾介绍
- 返回头节点
整体的时间复杂度o(n)
解答
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
//1.保存到数组翻转
let res = []
let p = head
while(p)
{
res.push(p)
p = p.next
}
let res2 = []
let i = 0
while(i<res.length) {
if(i+k<=res.length) {
res2.push(...(res.slice(i,i+k).reverse()))
i = i+k
} else {
res2.push(...res.slice(i))
break
}
}
head = new ListNode()
p = head
for(let i=0;i<res2.length;i++) {
let node = new ListNode(res2[i].val)
p.next = node
p = node
}
p.next = null
return head.next
};
根据代码,我们发现k个一组的链表翻转也是比较ok的