情形:甲和乙有些代办事项,每一个事项都有一个开始时间,和一个截止时间。但是甲和乙的代办事项可能会出现冲突,若在一个代码事项中,存在其他代办事项,则就认为是冲突。现要求合并甲和乙的代办事项,不能够有冲突。
解决:
由于我经常用java,所以就用java模拟该问题。
定义代办事项:
public class Node { private int startTime; private int endTime; Node cNode; }甲和乙的代办事项已经是有序的链表
初始化甲的代办事项:
Node nodeA = new Node(1, 2);// 初始化节点A nodeA.addNode(new Node(2, 6)); nodeA.addNode(new Node(3, 7)); nodeA.addNode(new Node(4, 9)); nodeA.addNode(new Node(7, 12)); nodeA.addNode(new Node(16, 19));
Node nodeB = new Node(2, 4); nodeB.addNode(new Node(3, 6)); nodeB.addNode(new Node(7, 10)); nodeB.addNode(new Node(9, 15)); nodeB.addNode(new Node(18, 20));注意:甲乙各自的代办事项中都可能存在冲突,合并后的代办事项也可能存在冲突。
基于此的话,我们考虑直接将甲和乙的代办事项合并,然后再将合并后的代办事项中冲突的事项给删除掉。
printNode(nodeA); printNode(nodeB); Node mergeNode=mergeWithNoSort(nodeA, nodeB);//将两个节点合并 printNode(mergeNode); Node deleteNode=deleteNode(mergeNode);//删除节点中冲突的节点 printNode(deleteNode);运行结果如图:
public static Node mergeWithNoSort(Node nodeA, Node nodeB) { Node tempNode = nodeA; // 合并nodeA 和nodeB // 采用插入删除,将nodeB插入到nodeA中 Node insertNode = nodeB; while (tempNode != null) { if (tempNode.cNode == null) { if (insertNode.startTime <= tempNode.startTime) { Node tempInsert = insertNode; insertNode.cNode = tempNode; tempNode = insertNode; insertNode = tempInsert; break; } else { tempNode.cNode = insertNode; return nodeA; } } else { if (insertNode.startTime <= tempNode.startTime) { Node tempInsert = insertNode; insertNode.cNode = tempNode; tempNode = insertNode; insertNode=tempInsert; break; } else if (insertNode.startTime>tempNode.startTime&&insertNode.startTime<=tempNode.cNode.startTime) { Node tempInsert=insertNode.cNode; insertNode.cNode=tempNode.cNode; tempNode.cNode=insertNode;//巧妙利用nodeB已经是有序,少写外面一个循环 insertNode=tempInsert; } else { tempNode=tempNode.cNode; } } } return nodeA; }
// 删除有冲突的节点 public static Node deleteNode(Node node) { Node tempNode = node; while (tempNode!=null&&tempNode.cNode != null) { if (tempNode.cNode.startTime < tempNode.endTime)// 有冲突,删除节点 { Node temp = tempNode.cNode; tempNode.cNode = temp.cNode; continue; } tempNode = tempNode.cNode; } return node; }
打印节点函数:
// 打印一个节点 public static void printNode(Node node) { Node tempNode = node; while (tempNode != null) { System.out.print("(" + tempNode.startTime + "," + tempNode.endTime + ")->"); tempNode = tempNode.cNode; } System.out.println(); }在节点的最后一个节点添加一个节点:
// 向节点后面添加一个节点 public void addNode(Node node) { Node tempNode = this; while (tempNode.cNode != null) { tempNode = tempNode.cNode; } tempNode.cNode = node; }其实仔细分析,这在逻辑上并不是太难。对于我一个很久没写过算法的人来说,当面试是时,没有写出来,悲剧,一面就被拒绝了,看来找工作前,一定要多写点代码,多复习数据结构啊。