算法題002 -- [刪除鏈表中重複的結點] by java

程序運行截圖:
在這裏插入圖片描述

public class Node {

	public static final int HEAD = 0X66;
	
	public int value;
	
	public int count;
	
	public Node preNode;
	
	public Node nextNode;
	
	public Node() {}
	
	public Node(int value,Node nextNode) {
		this.value = value;
		this.nextNode = nextNode;
	}
	
}
package algorithm2;

public class Algorithm2 {
	
	/*
	 * [刪除鏈表中重複的結點]
	 * 
	 * [題目] 在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。
	 * 例如,鏈表1->2->3->3->4->4->5 處理後爲 1->2->5
	 * 
	 * [解析] 主要考代碼的能力,注意邊界條件的考慮,指針判空等。
	 */

	public static void main(String[] args) {
		Node testNode = createTestLinked();
		printNode(testNode);
		testNode = filterNode(testNode);
		printNode(testNode);
	}

	/**
	 * 創建測試鏈表
	 * 爲了方便最後返回鏈表頭指針,我給鏈表創建了一個 HEAD 節點->
	 * 這樣不管後面的節點如何變動,我只要保證結果鏈表的結果正確,並且與 HEAD 節點依然鏈接在一起就好了
	 * @return
	 */
	private static Node createTestLinked() {
		Node node5 = new Node(5, null);
		Node node4_2 = new Node(4, node5);
		Node node4_1 = new Node(4, node4_2);
		Node node3_2 = new Node(3, node4_1);
		Node node3_1 = new Node(1, node3_2);
		Node node2 = new Node(2, node3_1);
		Node node1 = new Node(2, node2);
		node5.preNode = node5;
		node4_2.preNode = node4_1;
		node4_1.preNode = node3_2;
		node3_2.preNode = node3_1;
		node3_1.preNode = node2;
		node2.preNode = node1;
		Node headNode = new Node(Node.HEAD, node1);
		node1.preNode = headNode;
		return headNode;
	}

	/**
	 * 打印鏈表,不打印 HEAD 節點
	 * @param node
	 */
	private static void printNode(Node node) {
		Node preNode = node.nextNode;
		StringBuilder sb = new StringBuilder();
		sb.append(preNode.value + ":: count = " + preNode.count + "-> ");
		while (preNode.nextNode != null) {
			sb.append(preNode.nextNode.value + ":: count = " + preNode.nextNode.count + "-> ");
			preNode = preNode.nextNode;
		}
		System.out.println(sb.toString());
	}
	
	/**
	 *	刪除重複節點的方法,可惜的是這個方法的時間複雜度是 O(n^2)
	 *
	 *	其實還有一種有缺陷的思路 ->
	 *  那就類似於桶排序的思路:
	 *  如果知道取值value的取值範圍,並且跨度不大,在能接受範圍內的話->
	 *  可以以value爲index,爲這個鏈表的值創建一個數組,而數組的內容則是index作爲value出現在鏈表中的次數->
	 *  然後遍歷鏈表,將其與數組互爲對照,這樣也能知道重複的節點。然後由於這個方法的侷限性和缺陷就不編碼了。->
	 *  然而,一旦符合上面的一些限制,那麼這個思路的時間複雜度 O(n)
	 * @param node
	 * @return
	 */
	private static Node filterNode(Node node) {
		Node compare = node.nextNode;
		// 在 Node 節點中設置標記,在將每一個節點依次拿出來與所有節點對比時,如果相等標記遞增
		while (compare != null) {
			Node nextNode = node.nextNode;
			while (nextNode != null) {
				if (nextNode.value == compare.value) {
					compare.count++;
				}
				nextNode = nextNode.nextNode;
			}
			compare = compare.nextNode;
		}
		// 在全部比較之後再將重複的節點調節
		compare = node.nextNode;
		while(compare != null) {
			if(compare.count != 1) {
				compare.preNode.nextNode = compare.nextNode;
				compare.nextNode.preNode = compare.preNode;
			}
			compare = compare.nextNode;
		}
		return node;
	}
}

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