package algorithm.list;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @描述: 反转部分单向链表
* @思路:
* 1.找到from位置的前一个节点 和 找到to位置的后一个节点
* 2.反转from到to位置的链表 -- 注意判断"换头问题"
* 3.将部分链表同整体链表关联起来; -- 注意判断"换头问题"
* @复杂度:时间O(N) 空O(1)
* @链接:https://www.nowcoder.com/practice/f11155006f154419b0bef6de8918aea2?tpId=101&tqId=33176&tPage=1&rp=1&ru=/ta/programmer-code-interview-guide&qru=/ta/programmer-code-interview-guide/question-ranking
*/
class ReversePartList {
public static Node reversePartList(Node head, int from, int to) {
//找到from位置的前一个节点 和 找到to位置的后一个节点
Node node = head;
Node fPre = null;
Node tNext = null;
int lenght = 0;
while (node != null) {
lenght++;
fPre = lenght == from-1 ? node : fPre;
tNext = lenght == to+1 ? node : tNext;
node = node.getNext();
}
//校验输入数据的合法性
if (from > to || from < 1 || to > lenght) {
return head;
}
//反转from到to位置的链表,注意:要判断是否存在"换头问题",即fPre是否为null。
Node pre = fPre == null ? head : fPre.getNext();
Node currNode = pre.getNext();
pre.setNext(tNext); //目的:将反转后的链表,尾部同整个链表关联起来
Node next = null;
while(currNode != tNext) {
next = currNode.getNext();
currNode.setNext(pre);
pre = currNode;
currNode = next;
}
//不存在"换头问题"
if(fPre != null){
fPre.setNext(pre); // pre就是反转链表的第一个节点,目的:将反转后的链表,头部同整个链表关联起来
return head;
}
//存在"换头问题"
return pre;
}
public static void main(String[] args) {
Node head = Node.createNodeList(new Integer[]{1, 2, 3, 4, 5});
head = ReversePartList.reversePartList(head,2,3);
Node.printNodeList(head);
}
}
class Main4 {
public static void main(String[] args) throws IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(input.readLine());
String[] strings1 = input.readLine().split(" ");
Node head1 = Node.createNodeList(strings1);
String[] fromAndTo = input.readLine().split(" ");
int from = Integer.parseInt(fromAndTo[0]);
int to = Integer.parseInt(fromAndTo[1]);
head1 = ReversePartList.reversePartList(head1,from,to);
Node.printNodeList(head1);
}
}