写点什么

Week 08 命题作业

用户头像
卧石漾溪
关注
发布于: 2020 年 07 月 27 日

1.有两个单向链表(链表长度分别为 m, n) ,这两个单向链表有可能在某个元素合并,如下图所示的这样,也可能不合并。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并? 如果合并,找到合并的元素,也就是图中的 x 元素。

请用(伪)代码描述算法,并给出时间复杂度和空间复杂度。


解答:


import java.util.ArrayList;import java.util.List;
public class Test2 { public static void main(String[] args) { // 链表1数据初始化 MyLinkedList<String> list1 = new MyLinkedList<String>(); list1.addLast("a"); list1.addLast("b"); list1.addLast("x"); list1.addLast("y"); list1.addLast("z"); int m = list1.size();//链表1的长度 // 链表2数据初始化 MyLinkedList<String> list2 = new MyLinkedList<String>(); list2.addLast("d"); list2.addLast("e"); list2.addLast("f"); list2.addLast("x"); list2.addLast("y"); list2.addLast("z"); int n = list2.size();//链表2的长度 // 如果仅仅是判断两条链表是否相交,最简单的方法是判断两个链表的最后一个结点是否相等,如果相等,那么这两个链表就相交: // 此判断的时间复杂度为O(m+n) System.out.println("判断两个链表是否相交[时间复杂度O(m+n)="+(m+n)+"]:"+(list1.get(list1.size()-1).equals(list2.get(list2.size()-1)))); // 找出相交元素方法一: // 如果要求出哪些元素相交,可从任意一个链表进行遍历,然后每次遍历时判断第二个链表中是否包含了该元素: // 此时时间复杂度为O(m*n) int o1=0; List<String> resultList = new ArrayList<String>(); for(int i=0;i<list1.size();i++){ String tmp1 = list1.get(i); for(int j=0;j<list2.size();j++){ String tmp2 = list2.get(j); if(tmp1.equals(tmp2)){ resultList.add(tmp1); } o1++; } } System.out.println("以下是两个链表相交的元素[时间复杂度O(m*n)="+o1+"]:"); for(String temp : resultList){ System.out.println(temp); } /* 判断两个链表是否相交[时间复杂度O(m+n)=11]:true 以下是两个链表相交的元素[时间复杂度O(m*n)=30]: x y z */ }}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////下面是自定义单链表相关类///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//单链表节点类class Node<E> { // 元素值 E data; // 当前节点的下一节点的引用 Node<E> next;
Node(E element) { this.data = element; } Node(E element, Node<E> next) { this.data = element; this.next = next; }}
// 单链表类class MyLinkedList<E>{ int size = 0; // 记录链表的大小 Node<E> head; // 表示链表的头节点 // 在链表头添加节点 public void addHead(E data){ Node<E> node = new Node<E>(data); if(size==0){ head = node; }else{ node.next = head; head = node; } size++; } // 往链表末尾加入节点 public void addLast(E data) { // 实例化一个节点 Node<E> newNode = new Node<E>(data); // 判断头节点是否为空,如果是空就给他赋值 if (head == null) { head = newNode; }else{ // 接收head头指针的对象 Node<E> temp = head; // 遍历单链表,直到遍历到最后一个则跳出循环。 while (temp.next != null) { // 往后移动一个节点,指向下一个节点 temp = temp.next; } // temp为最后一个节点或者是头节点,将其next指向新节点 temp.next = newNode; } size++; } // 删除指定下标的节点 public boolean delete(int index) { if (index < 0 || index >= size()) { return false; } if (index == 0) { head = head.next; return true; } int i = 1; Node<E> preNode = head; Node<E> curNode = preNode.next; while (curNode != null) { if (i == index) { preNode.next = curNode.next; return true; } preNode = curNode; curNode = curNode.next; i++; } return false; } // 获取链表大小 public int size(){ return size; } // 根据下标获取节点值 public E get(int index){ if(index >= 0 && index < size()){ int i = 0; Node<E> tmp = head; while (tmp != null) { if(i == index){ return tmp.data; } tmp = tmp.next; i++; } } return null; } // 根据下标获取节点对象 public Node<E> getNode(int index){ if(index >= 0 && index < size()){ int i = 0; Node<E> tmp = head; while (tmp != null) { if(i == index){ return tmp; } tmp = tmp.next; i++; } } return null; }
// 打印单链表 public void printList() { Node<E> tmp = head; while (tmp != null) { System.out.println(tmp.data); tmp = tmp.next; } }}
复制代码


以上代码执行结果为:

判断两个链表是否相交[时间复杂度O(m+n)=11]:true			以下是两个链表相交的元素[时间复杂度O(m*n)=30]:			x			y			z
复制代码


2.请画出 DataNode 服务器节点宕机的时候, HDFS 的处理过程时序图。


解答:


用户头像

卧石漾溪

关注

还未添加个人签名 2020.05.04 加入

还未添加个人简介

评论

发布
暂无评论
Week 08 命题作业