这是我第一次实习面试的时候被问到的算法题,现在想想当时还是很年轻啊。
链表是数据结构的基础而且变化多端,可以考察的点非常的多,单链表反转应该是在面试中出现次数比较多的一道题了,我觉得它是在考一个人的基础,也考察的思维灵敏度。
例如给定1 -> 2 -> 3 -> 4 -> 5,转换成5 -> 4 ->3 -> 2 -> 1。
比较巧妙的一种方法就是递归判断,假设已经递归到最后一步1 -> 2 <- 3 <- 4 <- 5,只要把节点2指向节点1就可以了。有n 个节点,那么如果第一个节点后面的
n-1 个节点已经正确倒转了的话,我只要处理第一和第二个节点的指向关系就可以了。要是n-1个节点正确倒转,就先要n-2个节点倒转。。。这样递归下去直到只剩下最后一个节点,你可以看做它不是倒转也可以把它看做倒转。这就是递归的基线条件,而上面讲到的就是这个算法的递归条件,而且这样做也不用去考虑边界值问题。下面是代码实现:
节点结构:
package p_15_reverselist;
public class Node {
int val;
Node next;
}
构建链表:
package p_15_reverselist;
public class InitializeList {
public Node createList(int nodeNum) {
if(nodeNum <= 0) {
return null;
}
Node head = null;
int val = 0;
Node node = null;
while(nodeNum > 0) {
if(head == null) {
head = new Node();
head.val = val;
head.next = null;
node = head;
}else {
node.next = new Node();
node = node.next;
node.val = val;
node.next = null;
}
val++;
nodeNum--;
}
return head;
}
public void printList(Node node){
while(node != null) {
System.out.print(node.val+"->");
node = node.next;
}
System.out.println("null");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
InitializeList init = new InitializeList();
Node head = init.createList(6);
init.printList(head);
ReverseList rl = new ReverseList(head);
init.printList(rl.getReverseList());
}
}
反转列表:
package p_15_reverselist;
public class ReverseList {
private Node head;
private Node newHead;
public ReverseList(Node head){
this.head = head;
}
public Node reverse(Node node) {
if(node == null || node.next == null) {
newHead = node;
return node;
}
Node head = reverse(node.next);
head.next = node;
node.next = null;
return node;
}
public Node getReverseList(){
reverse(head);
return newHead;
}
}