经历了很多面试,面试官考察的算法无非是斐波那契数列和单链表反转,尽管是这些都是基础知识,然而我对单链表反转有更多的想法。
递归法是我早期在面试中使用的算法,很有逼格,写起来非常优雅,非常好理解。
先定义链表数据结构
static class Node { Integer data; Node next; } static Node readyNode() { Node linkNode1 = new Node(); linkNode1.data = 1; Node linkNode2 = new Node(); linkNode2.data = 2; Node linkNode3 = new Node(); linkNode3.data = 3; Node linkNode4 = new Node(); linkNode4.data = 4; Node linkNode5 = new Node(); linkNode5.data = 5; Node linkNode6 = new Node(); linkNode6.data = 6; linkNode1.next = linkNode2; linkNode2.next = linkNode3; linkNode3.next = linkNode4; linkNode4.next = linkNode5; linkNode5.next = linkNode6; return linkNode1; }
如上代码所示
static Node reverseLinkedList(Node node) { if (node == null || node.next == null) { return node; } else { Node headNode = reverseLinkedList(node.next); node.next.next = node; node.next = null; return headNode; } }
上图展示了递归后的效果。
如果注释掉第7行,会发生如上图所示的1、2号节点闭环问题。由于1号节点的next没有置空,依旧指向2号节点,所以遍历时候肯定存在环。
static Node reverseLinkedList(Node node) { Node previousNode = null; Node currentNode = node; Node headNode = null; while (currentNode != null) { Node nextNode = currentNode.next; if (nextNode == null) { headNode = currentNode; } currentNode.next = previousNode; previousNode = currentNode; currentNode = nextNode; } return headNode; }
LinkedList的反转
LinkedList没有提供反转链表的相关函数,以下是通过foreach实现链表反转
static LinkedList reverseLinkedList(LinkedList linkedList) { LinkedList<Object> newLinkedList = new LinkedList<>(); for (Object object : linkedList) { newLinkedList.add(0, object); } return newLinkedList; }想要知道更多的java应用技术那就加入我们吧!