描述
给定一个单链表,在链表中把第 L 个节点到第 R 个节点这一部分进行反转。
示例1
输入:
5
1 2 3 4 5
1 3
输出:
3 2 1 4 5
解题思路:
想要反转第from到第to这部分的链表,必须要找到from节点前一个fPre节点,以及to节点后一个节点tPos节点。找到后,对第from到第to这部分的链表进行反转,再接上fPre节点和tPos节点。
实现过程:
1、利用len记录链表的长度,每走一个节点就加一。如果当len等于from-1,就说明此时的fPre就是当前node1,同理,tPos等于to+1时,tPos就是当前node1。
while(node1!=null){
len++;
fPre=len==from-1?node1:fPre;
tPos=len==to+1?node1:tPos;
node1=node1.next;
}
2、判断边界条件
if(from>to||from<1||to>len){
return head;
}
3、初始化node1和node2位置
node1初始化是反转部分链表的第一个节点。
node2初始化为反转部分链表的第二个节点。
fPre等于空的话,就将head作为node1,否则就将fPre的下一个节点作为node1
node1的下一个节点就是node2
- 反转前先将node1指向tPos节点(反转后就是部分链表的最后一个节点)
- 进行反转
- 反转后将fPre节点指向部分链表最后一个节点node1(反转后就是部分链表的第一个节点)
import java.util.Scanner;
class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String[] n=in.nextLine().split(" ");
String[] num=in.nextLine().split(" ");
String[] LR=in.nextLine().split(" ");
Node node=transForNode(num);
node=reversePart(node,Integer.parseInt(LR[0]),Integer.parseInt(LR[1]));
show(node);
}
//打印链表
public static void show(Node head){
while(head!=null){
System.out.print(head.value+" ");
head=head.next;
}
System.out.println();
}
//数组转链表
public static Node transForNode(String[] nums) {
Node head = new Node(Integer.parseInt(nums[0]));
Node cur = head;
for(int i = 1; i < nums.length; i++) {
cur.next = new Node(Integer.parseInt(nums[i]));
cur = cur.next;
}
return head;
}
public static Node reversePart(Node head,int from,int to){
int len=0;
Node node1=head;
Node fPre=null;
Node tPos=null;
while(node1!=null){
len++;
fPre=len==from-1?node1:fPre;
tPos=len==to+1?node1:tPos;
node1=node1.next;
}
if(from>to||from<1||to>len){
return head;
}
node1= fPre==null?head:fPre.next;//fPre前一个是空,head节点是node1,不为空,node1就是fPre的下一个
Node node2=node1.next;//node2初始化为node1的下一个
node1.next=tPos;//将node1指向tPos
Node next=null;//定义一个next
while(node2!=tPos){
next=node2.next;
node2.next=node1;
node1=node2;
node2=next;
}
if(fPre!=null){//fPre不为空就返回head
fPre.next=node1;//fPre连到反转后node1节点
return head;
}
return node1;//fPre为空返回反转完的第一个节点node1
}
}