题目:
分别实现反转单向链表和双向链表的函数。
要求:
如果链表长度为N,时间复杂度为O(N),额外空间复杂度要求为O(1)。
程序:
反转单向链表:
public class Node{
public Node(int data){
this.value=data;
}
public int value;
public Node next;
}
public static Node reverseList(Node node){
Node pre=null;
Node next=null;
while(head!=null){
next=head.next;
head.next=pre;
pre=head;
head=next;
}
return pre;
}
反转双向链表:
public class DoubleNode{
public DoubleNode(int data){
this.value=data;
}
public int value;
public DoubleNode next;
public DoubleNode pre;
}
public static DoubleNode reverseList(DoubleNode node){
DoubleNode pre=null;
DoubleNode next=null;
while(head!=null){
next=head.next;
head.next=pre;
head.pre=next;
pre=head;
head=next;
}
return pre;
}
题目二:
反转部分单向链表:
给定一个单向链表的头结点head,以及两个整数from和to,在单向链表上把第from个节点到第to个节点这一部分进行反转。
如果不满足1<=from<=to<=N,则不用调整。
核心思路:
找到from的前一个节点和to的后一个节点。
public class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public static Node reversePart(Node node,int from,int to){
int len=0;
Node node1=head;
Node fPre=null;
Ndoe tPos=null;
while(node1!=null){
len++;
//找到from节点的前一个结点
fPre=len==from-1?node1:fPre;
//找到to节点的后一个节点
tPos=len==to+1?node1:tPos;
}
//不满足条件时,直接返回head
if (from>to||from<1||to>len) {
return head;
}
//node1表示from的位置上的节点
//判断反转的部分是否包含头结点,由于最后是返回head还是返回node1是不确定的,所以这一步的判断也是很必要的
//如果反转的部分包含头结点,那么返回node1,因为head改变了,否则返回head
node1=fPre==null?head:fPre.next;
Node node2=node1.next;
//将要反转的第一个节点与tPos连接起来
node1.next=tPos;
Node next=null;
while(node2!=tPos){
next=node2.next;
node2.next=node1;
node1=node2;
node2=next;
}
if (fPre!=null) {
//将要反转的最后一个节点与node1连接
fPre.next=node1;
return head;
}
return node1;
}