1.首先时反转链表,简单是简单,但总是写错!
第一:总直接dummyNode.next赋值head,不可行呀,先指向的时null(pre)
第二:循环内总是cur=cur.next,明明最开始记录了,此时这样写链表的cur指针已经变了
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
function ReverseList( head ) {
// write code here
let vHeadNode=new ListNode(0);
let cur=head;
while(cur){
let next=cur.next;
cur.next=vHeadNode.next;
vHeadNode.next=cur;
cur=next;
}
return vHeadNode.next;
}
module.exports = {
ReverseList : ReverseList
};
2.在链表指定区间进行反转
此题核心就是`找到区间的pre和next指针`,然后进行反转,最后连接链表
找指针时条件,前一:m-,后一:cur.next
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
function reverseBetween( head , m , n ) {
// write code here
let vHeadNode=new ListNode(0);
vHeadNode.next=head;
let cur=vHeadNode;
let leftPre,rightNext;
//找leftPre&rightNext
//分两半,left&待反转&右
for(let i=0;i<n;i++){
if(i===m-1)leftPre=cur;
cur=cur.next;
}
rightNext=cur.next;
//断开右部分
cur.next=null;
//核心
let [start,end]=reverseList(leftPre.next);
leftPre.next=start;
end.next=rightNext;
return vHeadNode.next;
}
function reverseList(head){
//返回链表前后节点!!!
let vHead=new ListNode(0);
let cur=head;
while(cur){
let next=cur.next;
cur.next=vHead.next;
vHead.next=cur;
cur=next;
}
return [vHead.next,head]
}
module.exports = {
reverseBetween : reverseBetween
};
3. k个为一组进行反转(⭐⭐⭐)
此题较麻烦,思路就是先判断是否够k个不够直接返回结果,够的话先找到下一组的起始节点(上一组的结束首先赋值为dummy),记录下一组的起始节点bong断开后续链表,反转此组并返回新的起始节点,将此组链表和前后链表进行连接,并更新上一节点结束&cur当前节点。
// 1. 检测剩余节点是否足够k个
// 2. 切割当前分组并记录下一组起点
// 3. 翻转当前分组
// 4. 连接分组
// 5. 移动指针准备处理下一组
特别注意指针,preEnd|cur
|groupStart|groupEnd|nextGroupStart 为global指针
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
function reverseKGroup(head, k) {
// write code here
const dummy = new ListNode(-1); // 虚拟头节点简化操作
dummy.next=head;
//核心一个迁移链表的End和当前节点
let prevGroupEnd = dummy; // 上一组的尾节点
let current = head;
while (current) {
// 1. 检测剩余节点是否足够k个
let groupStart = current;
let groupEnd = prevGroupEnd;
for (let i = 0; i < k; i++) {
groupEnd = groupEnd.next;
if (!groupEnd) return dummy.next; // 不足k个直接返回
}
// 2. 切割当前分组并记录下一组起点
const nextGroup = groupEnd.next;
groupEnd.next = null; // 切断当前分
// 3. 翻转当前分组
const [reversedHead, reversedTail] = reverseSubList(groupStart);
// 4. 连接分组
prevGroupEnd.next = reversedHead; // 连接上一组
reversedTail.next = nextGroup; // 连接下一组
// 5. 移动指针准备处理下一组
prevGroupEnd = reversedTail;
current = nextGroup;
}
return dummy.next;
}
//反思一下自己吧!!!简单但请仔细
function reverseSubList(head) {
let dummyNode = new ListNode(0);
let cur = head;
while (cur) {
let next = cur.next;
cur.next = dummyNode.next;
dummyNode.next = cur;
cur = next;
}
return [dummyNode.next, head];
}
module