阿里电话面试-解决两个冲突的事项

    情形:甲和乙有些代办事项,每一个事项都有一个开始时间,和一个截止时间。但是甲和乙的代办事项可能会出现冲突,若在一个代码事项中,存在其他代办事项,则就认为是冲突。现要求合并甲和乙的代办事项,不能够有冲突。

  解决:

   由于我经常用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);
运行结果如图:

阿里电话面试-解决两个冲突的事项_第1张图片

 
    将两个节点合并函数:

        

	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;
	}
    其实仔细分析,这在逻辑上并不是太难。对于我一个很久没写过算法的人来说,当面试是时,没有写出来,悲剧,一面就被拒绝了,看来找工作前,一定要多写点代码,多复习数据结构啊。

   

你可能感兴趣的:(数据结构,算法,工作,面试,阿里)