簡單描述,多條鏈表,找出他們的交叉點,注意,鏈表自身也可能交叉
演算法:
step2:處理鏈表節點,將節點放入臨時的List中,進入下一個節點,判斷臨時List與全域節點集合中是否存在該節點,如果是,則說明是迴圈鏈表,將節點加入到結果集中,然後跳出,否則,繼續直到結束
step3:將臨時List中所有節點,加入到全域節點集,跳轉step2,知道所有鏈表處理完畢
step4:列印結果
Node.java
/**<br /> *<br /> */<br />/**<br /> * @author jie.xiang<br /> *<br /> */<br />public class Node {<br />private String name;<br />private Node nextNode;<br />public Node(String name) {<br />this.name = name;<br />}<br />public String getName() {<br />return name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}<br />public Node getNextNode() {<br />return nextNode;<br />}<br />public void setNextNode(Node nextNode) {<br />this.nextNode = nextNode;<br />}<br />@Override<br />public String toString() {<br />// TODO Auto-generated method stub<br />String str = name;<br />if (nextNode != null) {<br />str += "-->" + nextNode.getName();<br />}<br />return str;<br />}<br />}<br />
DataFactory.java
import java.util.ArrayList;<br />import java.util.List;<br />/**<br /> *<br /> */<br />/**<br /> * @author jie.xiang<br /> *<br /> */<br />public final class DataFactory {<br />public static List<Node> createNodeList() {<br />List<Node> list = new ArrayList<Node>();<br />Node node1 = new Node("1");<br />Node node2 = new Node("2");<br />Node node3 = new Node("3");<br />Node node4 = new Node("4");<br />Node node5 = new Node("5");<br />Node node6 = new Node("6");<br />Node node7 = new Node("7");<br />Node node8 = new Node("8");<br />Node node9 = new Node("9");<br />Node node10 = new Node("10");<br />Node node11 = new Node("11");<br />Node node12 = new Node("12");<br />Node node13 = new Node("13");<br />Node node14 = new Node("14");<br />node1.setNextNode(node2);<br />node2.setNextNode(node3);<br />node3.setNextNode(node4);<br />node4.setNextNode(node5);<br />node5.setNextNode(node3);<br />list.add(node1);<br />node6.setNextNode(node2);<br />list.add(node6);<br />node7.setNextNode(node8);<br />node8.setNextNode(node9);<br />node9.setNextNode(node5);<br />list.add(node7);<br />node10.setNextNode(node8);<br />list.add(node10);<br />node11.setNextNode(node12);<br />list.add(node11);<br />node13.setNextNode(node8);<br />list.add(node13);<br />node14.setNextNode(node3);<br />list.add(node14);<br />return list;<br />}<br />}<br />
CrossNodeCounter.java
import java.util.ArrayList;<br />import java.util.HashMap;<br />import java.util.HashSet;<br />import java.util.List;<br />import java.util.Map;<br />import java.util.Set;<br />/**<br /> *<br /> */<br />/**<br /> * @author jie.xiang<br /> *<br /> */<br />public class CrossNodeCounter {<br />private Set<Node> nodes = new HashSet<Node>();<br />private Map<Node, Integer> result = new HashMap<Node, Integer>();<br />public void findCrossNodes(List<Node> list) {<br />for (Node node : list) {<br />findCrossNode(node);<br />}<br />}<br />/**<br /> * 對當前的鏈表做出處理,找出該鏈表的交叉點以及將點放入到一個統一的集合表中保持<br /> *<br /> * @param node<br /> */<br />public void findCrossNode(Node node) {<br />List<Node> tempList = new ArrayList<Node>();<br />tempList.add(node);<br />node = node.getNextNode();<br />while (node != null) {<br />if (tempList.contains(node) || nodes.contains(node)) { // 處理迴圈鏈表的情況<br />addNode(node);<br />break;<br />} else {<br />tempList.add(node);<br />node = node.getNextNode();<br />}<br />}<br />addNodesToSet(tempList);<br />}<br />/**<br /> * 儲存鏈表的點<br /> *<br /> * @param tempList<br /> */<br />private void addNodesToSet(List<Node> tempList) {<br />for (Node node : tempList) {<br />nodes.add(node);<br />}<br />}<br />private void addNode(Node node) {<br />Integer value = result.get(node);<br />if (value == null) {<br />value = 2;// 既然是交叉點,預設有兩條線<br />} else {<br />value++;<br />}<br />result.put(node, value);<br />}<br />public void printlnResult() {<br />Set<Node> keys = result.keySet();<br />for (Node node : keys) {<br />System.out.println("(Name)" + node.getName() + ":"<br />+ result.get(node) + "Lines)");<br />}<br />}<br />public static void main(String[] args) {<br />CrossNodeCounter counter = new CrossNodeCounter();<br />counter.findCrossNodes(DataFactory.createNodeList());<br />counter.printlnResult();<br />}<br />}<br />
資料圖如下:
測試結果為:
(Name)2:2Lines)
(Name)3:3Lines)
(Name)8:3Lines)
(Name)5:2Lines)
心得,該問題主要是基於集合的使用,主要是搞清楚怎麼存放節點