要求:
给定一个单向链表的头文件head,以及两个整数from和to,在单向链表上把第from个节点到第to个节点这一部分进行反转。
例如: 1->2->3->4->5->null,from = 2,to = 4;调整后为 1->4->3->2->5->null。
注意:
1.如果链表长度为N,时间复杂度要求为O(N),额外时间复杂要求为O(1)。
2.如果不满足 1<=from<=to<=N,则不用调整。
思考:
整个过程处理如下:
1.先判断是否满足1<=from<=to<=N,如果不满足则直接返回原来的头节点。
2.找到第from-1个节点fPre和第to+1个节点tPos。把反转的部分先反转,然后正确地连接fPre和tPos。
3.如果fPos为null,说明反转部分是包含头节点的,则返回新的头节点;如果fPre不为null,则返回旧的头节点。
实现代码
Node.java
package algorithm_12;
public class Node {
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
algorithm_12.java
package algorithm_12;
public class algorithm_12 {
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;
Node node2 = node1.next;
node1.next = tPos;
Node next = null;
while(node2 != tPos){
next = node2.next;
node2.next = node1;
node1 = node2;
node2 = next;
}
if(fPre != null){
fPre.next = node1;
return head;
}
return node1;
}
public static Node init(Node head){
for (int i = 2; i < 15; i++){
head.next = new Node(i);
head = head.next;
}
return head;
}
public static void print(Node head){
Node cur = head;
while (cur != null) {
System.out.print(cur.value + " ");
cur = cur.next;
}
System.out.print(" \n");
}
public static void main(String[] args) {
Node test = new Node(1);
init(test);
System.out.println("Before reversePart:");
print(test);
System.out.println("After reverseList:");
print(reversePart(test, 3, 8));
}
}
实验结果:
Before reversePart:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
After reverseList:
1 2 8 7 6 5 4 3 9 10 11 12 13 14