问题描述
- “ A,B,C,D,E,F”
它们属于N个不同的链接列表
- “ A-> C-> D”,“ B-> E”,“ F”
我只能从指针获得的信息是“孩子”知道“父母”,反之则不然。
如果能在下面的代码优化中获得一些指导,或者我的处理方法错误,将不胜感激。
for (Pointer i: listofPointers) {
if (!i.hasParent())
// no parent,its a root node
rootNodes.add(i.getId());
else {
// parent -> child
parentChild.put(i.getParent().getId(),i.getId());
}
}
// iterate through the head/roots
for (String i : rootNodes) {
LinkedList<String> templist = new LinkedList<>();
LinkedList<Map<String,String>> temp = new LinkedList<>();
String tempNow = i;
//construct our linked list,start by the head and getting the child until we have nothing left
do{
if (templist.size() == 0)
System.out.println("Parent - " + tempNow);
else
System.out.println("Child - " + tempNow);
templist.add(tempNow);
if (parentChild.containsKey(tempNow))
tempNow = parentChild.get(tempNow);
else
break;
}while(true);
linkedListHashMap.put(i,templist);
}
解决方法
我将创建一个Map
,该Pointer
通过其父级(实际上是边缘的Map
)映射每个List
,除了需要单独存储的根节点。之后,您可以通过重复遍历图直到没有进一步的映射来重建public Collection<List<Pointer>> group(Collection<Pointer> pointers) {
if(pointers.isEmpty()) {
return Collections.emptyList();
}
List<Pointer> roots = new ArrayList<>();
Map<Pointer,Pointer> parents = new HashMap<>(pointers.size());
for(Pointer pointer : pointers) {
if(pointer.hasParent()) {
parents.put(pointer.getParent(),pointer);
} else {
roots.add(pointer);
}
}
List<List<Pointer>> results = new ArrayList<>(roots.size());
for(Pointer root : roots) {
List<Pointer> list = new LinkedList<>();
list.add(root);
Pointer current = parents.get(root);
while(current != null) {
list.add(current);
current = parents.get(current);
}
results.add(list);
}
return results;
}
。
Pointer a = new Pointer("A");
Pointer c = new Pointer("C",a);
Pointer d = new Pointer("D",c);
Pointer b = new Pointer("B");
Pointer e = new Pointer("E",b);
Pointer f = new Pointer("F");
Collection<Pointer> pointers = Arrays.asList(a,b,c,d,e,f);
Collection<List<Pointer>> grouped = group(pointers);
// result: A -> C-> D ; B -> E ; F
对于您输入的内容:
import { component } from "knockout-decorators";
interface IPaginatorParams {
currentPageIndex: KnockoutObservable<number>;
maxPageIndex: KnockoutObservable<number>;
}
@component("paginator",require("./PaginatorComponent.html"),require("./PaginatorComponent.scss")
)
export class PaginatorComponent {
currentPageIndex: KnockoutObservable<number>;
maxPageIndex: KnockoutObservable<number>;
constructor(params: IPaginatorParams) {
const self = this;
self.currentPageIndex = params.currentPageIndex;
self.maxPageIndex = params.maxPageIndex;
}
}
,
虽然有一些直接的解决方案可以在原始列表的顶部构建其他数据结构,但我认为找到一个需要恒定数量的额外内存的解决方案(如以下所示)会很有趣:
boolean sorted = false;
while (!sorted) {
sorted = true;
for (Element element: elements) {
Element parent = element.parent;
if (parent != null) {
Element grandParent = parent.parent;
if (grandParent != null && parent.value > grandParent.value) {
element.parent = grandParent;
parent.parent = grandParent.parent;
grandParent.parent = parent;
sorted = false;
}
}
}
}
// Now the tails of all lists are sorted,only the heads
// (first elements) may be misplaced
for (Element element : elements) {
Element parent = element.parent;
Element child = null;
while (parent != null && element.value > parent.value) {
if (child != null)
child.parent = parent;
element.parent = parent.parent;
parent.parent = element;
child = parent;
parent = element.parent;
}
}
这个想法是当对所有列表进行排序时,每个元素都不得大于其父元素。因此,如果我们看到A->B->C->...
和B > C
,那么我们将该片段重新排列为A->C->B->...
。我们这样做,直到没有要重新排列的片段为止,这意味着所有列表的尾部都被排序了,只有头部(第一个元素)可能会错位。
现在,我们寻找类似于A->B->...
的片段,其中A > B
。因为只有头可能会放错位置,而A
显然会放错位置,所以A
是头,即没有A的子代。因此我们可以遍历从A
开始的列表,在此列表中找到A
的位置,然后将A
移动到那里,而不必更新A
的子级,因为保证A
没有子级。>
以下是对随机数据运行的示例:
Original:
78->77->2->39->67->78->98->
86->30->71->90->86->97->98->30->88->31->67->19->36->5->57->16->
7->16->19->12->74->98->55->60->38->25->2->37->45->92->3->52->24->43->41->84->95->73->77->19->91->15->29->60->
17->94->25->
34->80->
51->
68->23->1->89->5->17->67->35->97->26->57->38->
89->84->
58->
8->5->87->43->8->
72->60->
41->49->28->92->84->
41->33->15->8->55->40->16->58->13->86->35->16->77->71->
53->13->
After the first loop:
78->2->39->67->77->78->98->
86->5->16->19->30->30->31->36->57->67->71->86->88->90->97->98->
7->2->3->12->15->16->19->19->24->25->29->37->38->41->43->45->52->55->60->60->73->74->77->84->91->92->95->98->
17->25->94->
34->80->
51->
68->1->5->17->23->26->35->38->57->67->89->97->
89->84->
58->
8->5->8->43->87->
72->60->
41->28->49->84->92->
41->8->13->15->16->16->33->35->40->55->58->71->77->86->
53->13->
After the second loop:
84->89->
5->8->8->43->87->
2->39->67->77->78->78->98->
13->53->
17->25->94->
28->41->49->84->92->
8->13->15->16->16->33->35->40->41->55->58->71->77->86->
60->72->
34->80->
51->
5->16->19->30->30->31->36->57->67->71->86->86->88->90->97->98->
58->
1->5->17->23->26->35->38->57->67->68->89->97->
2->3->7->12->15->16->19->19->24->25->29->37->38->41->43->45->52->55->60->60->73->74->77->84->91->92->95->98->