题目介绍
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗? 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
自己的思路比较混乱,虽然也可以提交通过,但是实在写的比较差,就是用二维数据,记录需要反转的节点,尾部节点的连接,然后再遍历二维数据进行反转,把每个二维数组的头部和尾部相连即可
function reverseList(head) {
if(!head) return null
let cur = head
let pre = null // 这里会组成一个新的链表返回
// 1 => 2 = 3 => 4 => 5
while(cur) {
// 暂存下一个节点
let nex = cur.next
// 这里断开了之前的next节点,设置为上一个节点
cur.next = pre
//
pre = cur
cur = nex
}
return pre
}
var reverseKGroup = function(head, k) {
if (!head) return null
let arrList = []
let arr = []
let arr3 = []
let j = 0
for (let i = 0; i <= k; i++) {
if (!head) break
if (i === k) {
i = 0
arrList.push(arr)
arr[arr.length - 1].next = null
arr3.push([arr[arr.length - 1], arr[0]])
arr = []
}
arr.push(head)
head = head.next
}
if (arr.length === k) {
arrList.push(arr)
arr3.push([arr[arr.length - 1], arr[0]])
}
for (let i = 0 ; i < arrList.length; i++) {
reverseList(arrList[i][0])
}
for (let i = 0; i < arr3.length - 1; i++) {
arr3[i][1].next = arr3[i + 1][0]
}
if (arr.length !== k && arr.length) {
arr3[arr3.length - 1][1].next = arr[0]
}
return arr3[0][0]
};
转LeetCode上大神的解题思路,个人感觉这个比较好理解
- 链表分区为已翻转部分+待翻转部分+未翻转部分
- 每次翻转前,要确定翻转链表的范围,这个必须通过 k 此循环来确定
- 需记录翻转链表前驱和后继,方便翻转完成后把已翻转部分和未翻转部分连接起来
- 初始需要两个变量 pre 和 end,pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾
- 经过k此循环,end 到达末尾,记录待翻转链表的后继 next = end.next
- 翻转链表,然后将三部分链表连接起来,然后重置 pre 和 end 指针,然后进入下一次循环
- 特殊情况,当翻转部分长度不足 k 时,在定位 end 完成后,end==null,已经到达末尾,说明题目已完成,直接返回即可
作者:reals 链接:leetcode-cn.com/problems/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
function reverseList(head) {
if(!head) return null
let cur = head
let pre = null
while(cur) {
let nex = cur.next
cur.next = pre
pre = cur
cur = nex
}
return pre
}
var reverseKGroup = function(head, k) {
if (k === 1) return head
// 虚拟节点
let dummy = new ListNode(-1, head)
//
let pre = dummy
let end = dummy
while(end.next) {
for (let i = 0; i < k && end; i++) {
end = end.next
}
if (end === null) break
// 找到需要反转的头部
let start = pre.next
// 暂存下一个节点
let next = end.next
// 断开连接
end.next = null
// reverseList会返回新的头部
pre.next = reverseList(start)
// 之前的头变成了尾部,所以重新建立 下一个节点的连接
start.next = next
// 记录上一次反转的尾部
pre = start // 2
// 下一次反转开始的位置
end = pre
}
return dummy.next
};