代码
public class Test {
public static class ListNode {
Object value;
ListNode next;
ListNode(Object obj) {
value = obj;
}
@Override
public String toString() {
return "ListNode{" +
"value=" + value +
", next=" + next +
'}';
}
}
/**
* 根据下标替换链表值
* 1->2->3->4->5->6->null,m=2,n=4,条件:0 ≤ m≤ n ≤ list.length,n>list.length会空指针
* 1->2->5->4->3->6->null
* @param head
* @param m:前面位置的下标,从0开始
* @param n:后面位置的下标,从0开始
* @return
*/
public static ListNode reverseList(ListNode head, int m, int n) {
if (head == null || m >= n) {//规范的代码都会做防空判断
return head;
}
ListNode dummyPrev = new ListNode(-1);//伪装头节点
//dummyPrev.next始终指向当前头节点,避免交换的是头节点导致指向丢失
dummyPrev.next = head;
head = dummyPrev;//ListNode{value=-1, next=ListNode{value=1, next=ListNode{value=2, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}}}
for (int i = 0; i < m; i++) {//遍历到下标m的前一个node止
head = head.next;
/*
执行第1次,i=0
ListNode{value=1, next=ListNode{value=2, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}}
执行第2次,i=1
ListNode{value=2, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}
执行第3次,i=2
跳出
*/
}
/*
nNode=prev
postN=current
*/
ListNode prevM = head;//换位前的m前一节点
ListNode mNode = head.next;//换位前的m节点
ListNode nNode = mNode;//定义n节点,起始位置和m位置相同
ListNode postN = nNode.next;//定义操作n节点,代表后续执行的节点,即current
/*
prevM:ListNode{value=2, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}}
mNode:ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}
nNode:ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}
postN:ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}
*/
for (int i = m; i < n; i++) {//m开始遍历到n止,能进来,说明下postN还没走到n下标
/*
单链表反转的核心:
ListNode next => current.next;//临时变量存储当前节点的next
current.next => prev;//当前节点的next指向上一个头节点
prev => current;//重新指向之后,当前节点重新赋值头节点
current => next;//操作完成,赋值当前节点的下一个为当前节点
*/
ListNode next = postN.next;
postN.next = nNode;
nNode = postN;
postN = next;
}
/*
postN出参为nNode的后一节点位置,
当n=list.length,postN=null
当n>list.length会在上面的循环postN.next发生空指针异常
*/
mNode.next = postN;//m节点的next指向当前操作节点
prevM.next = nNode;//m前节点的next指向n节点
return dummyPrev.next;
}
public static void main(String[] args) {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
ListNode node6 = new ListNode(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = null;
System.out.println(node1);//ListNode{value=1, next=ListNode{value=2, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=6, next=null}}}}}}
reverseList(node1, 2, 4);
System.out.println(node1);//ListNode{value=1, next=ListNode{value=2, next=ListNode{value=5, next=ListNode{value=4, next=ListNode{value=3, next=ListNode{value=6, next=null}}}}}}
reverseList(node1, 0, 5);
System.out.println(node6);//ListNode{value=6, next=ListNode{value=3, next=ListNode{value=4, next=ListNode{value=5, next=ListNode{value=2, next=ListNode{value=1, next=null}}}}}}
reverseList(node6, 0, 6);//java.lang.NullPointerException
}