每天一道算法題——鏈表反轉

這是我第一次實習面試的時候被問到的算法題,現在想想當時還是很年輕啊。
鏈表是數據結構的基礎而且變化多端,可以考察的點非常的多,單鏈表反轉應該是在面試中出現次數比較多的一道題了,我覺得它是在考一個人的基礎,也考察的思維靈敏度。
例如給定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;
	}
	
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章