[算法]反转单向链表和双向链表
题目:
分别实现反转单向链表和双向链表的函数。
要求:
如果链表长度为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;
}