第八周课后作业
发布于: 2020 年 07 月 27 日
作业一:
有两个单向链表(链表长度分别为 m,n),这两个单向链表有可能在某个元素合并,如下图所示的这样,也可能不合并。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并?如果合并,找到合并的元素,也就是图中的 x 元素。
请用(伪)代码描述算法,并给出时间复杂度和空间复杂度。
大概思路是:从两个链表的后面往前来对比查找,遇到不相等的两个节点就停止查找,然后看前一个节点是否相等,相等则有交叉。
核心代码
public static void main(String[] args) {
//初始化测试数据,没考虑空链表
//initLists();
int minLength = Math.min(mListLength, nListLength);
int maxLength = Math.max(mListLength, nListLength);
ListNode mergedNode = null;
ListNode mListCompareNode;
ListNode nListCompareNode;
int mListCompareIndex;
int nListCompareIndex;
//从后往前取
for (int indexFromLast = 0; indexFromLast < minLength; indexFromLast++) {
mListCompareIndex = mListLength - indexFromLast - 1;
nListCompareIndex = nListLength - indexFromLast - 1;
mListCompareNode = mListFirstNode;
nListCompareNode = nListFirstNode;
//由于是单向链表,所以需要从头部开始遍历
for (int i = 1; i < maxLength - indexFromLast;i++) {
if (i <= nListCompareIndex) {
nListCompareNode = nListCompareNode.getNext();
}
if (i <= mListCompareIndex) {
mListCompareNode = mListCompareNode.getNext();
}
}
//发现节点不相等,则停止查找。相等则继续往前查找
if (nListCompareNode.equals(mListCompareNode)) {
mergedNode = nListCompareNode;
} else {
break;
}
}
//判断是否有交叉
System.out.println("是否有合并: " + Objects.nonNull(mergedNode) + " 合并的元素:" + mergedNode);
}
复制代码
由于用到了两个 for 循环,所以时间复杂度为 O(n^2)。没有用到额外的空间,所以空间复杂度为 O(1)。
优化思考:也许通过减少第二个 for 嵌套,用数组来保存,就能减少不少时间复杂度,虽然用了额外空间。
完整代码:
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Objects;
public class MergedNodeFinder {
private static int mListLength;
private static int nListLength;
private static ListNode mListFirstNode;
private static ListNode nListFirstNode;
public static void main(String[] args) {
//初始化测试数据,没考虑空链表
initLists();
int minLength = Math.min(mListLength, nListLength);
int maxLength = Math.max(mListLength, nListLength);
ListNode mergedNode = null;
ListNode mListCompareNode;
ListNode nListCompareNode;
int mListCompareIndex;
int nListCompareIndex;
//从后往前取
for (int indexFromLast = 0; indexFromLast < minLength; indexFromLast++) {
mListCompareIndex = mListLength - indexFromLast - 1;
nListCompareIndex = nListLength - indexFromLast - 1;
mListCompareNode = mListFirstNode;
nListCompareNode = nListFirstNode;
//由于是单向链表,所以需要从头部开始遍历
for (int i = 1; i < maxLength - indexFromLast;i++) {
if (i <= nListCompareIndex) {
nListCompareNode = nListCompareNode.getNext();
}
if (i <= mListCompareIndex) {
mListCompareNode = mListCompareNode.getNext();
}
}
//发现节点不相等,则停止查找。相等则继续往前查找
if (nListCompareNode.equals(mListCompareNode)) {
mergedNode = nListCompareNode;
} else {
break;
}
}
//判断是否有交叉
System.out.println("是否有合并: " + Objects.nonNull(mergedNode) + " 合并的元素:" + mergedNode);
}
private static void initLists() {
/*
//merge: null
ListNode cNode = new ListNode('c', null);
ListNode bNode = new ListNode('b', cNode);
mListFirstNode = new ListNode('a', bNode);
mListLength = 3;
ListNode fListNode = new ListNode('f', null);
ListNode eListNode = new ListNode('e', fListNode);
nListFirstNode = new ListNode('d', eListNode);
nListLength = 3;*/
//merge: c
ListNode cNode = new ListNode('c', null);
ListNode bNode = new ListNode('b', cNode);
mListFirstNode = new ListNode('a', bNode);
mListLength = 3;
ListNode eListNode = new ListNode('e', cNode);
nListFirstNode = new ListNode('d', eListNode);
nListLength = 3;
/*
//merge: c
ListNode dNode = new ListNode('d', null);
ListNode cNode = new ListNode('c', dNode);
ListNode bNode = new ListNode('b', cNode);
mListFirstNode = new ListNode('a', bNode);
mListLength = 4;
nListFirstNode = new ListNode('e', cNode);
nListLength = 3;
//merge: a
ListNode dNode = new ListNode('d', null);
ListNode cNode = new ListNode('c', dNode);
ListNode bNode = new ListNode('b', cNode);
mListFirstNode = new ListNode('a', bNode);
mListLength = 4;
ListNode eListNode = new ListNode('f', mListFirstNode);
nListFirstNode = new ListNode('e', eListNode);
nListLength = 6;
//merge: null
mListFirstNode = new ListNode('a', null);
mListLength = 1;
nListFirstNode = new ListNode('b', null);
nListLength = 1;
*/
}
/*
inner class
*/
@Data
@AllArgsConstructor
private static class ListNode {
private Object value;
private ListNode next;
}
}
复制代码
作业二:
请画出 DataNode 服务器节点宕机的时候,HDFS 的处理过程时序图。
没时间做,个人也不太清楚,有待学习
划线
评论
复制
发布于: 2020 年 07 月 27 日阅读数: 59
版权声明: 本文为 InfoQ 作者【iHai】的原创文章。
原文链接:【http://xie.infoq.cn/article/2300ffc909aaf54bd25cf8218】。文章转载请联系作者。
iHai
关注
还未添加个人签名 2018.07.26 加入
还未添加个人简介
评论