我有一个这样的链接列表:
public class Node {
public Node next;
public Node prev;
public int length;
public int weight;
}
我正在尝试使用特定长度作为窗口来查找非圆形链表(具有明确的开始和结束)的滚动密度。这增加了复杂性,因为端节点仅使用权重的百分比。
这意味着给定3个节点
A (L: 10, W:10) -> B (L: 5, W:10) -> C (L:20, W:5)
(其中L表示长度,W表示重量)
和节点9
的{{1}}窗口将使用所有节点B,现在它有一个4的窗口。它会在C和A之前和之后均匀地分割窗口。
因此密度为:
B
这个常见的情况不是我正在努力的部分,它是左侧不够的时候的结束点,窗口应该从右侧看更多,反之亦然。还有一种情况是两边都没有足够的长度。
我不确定是否应该实现递归函数或循环。我知道循环需要较少的计算,但递归函数可能更容易理解。
案例1:链表中只有一个节点 取1节点的密度忽略窗口
案例2:左/右侧的长度不够 从右/左侧取下剩余部分。
案例3:两侧的长度不够,但不只有1个节点。 占用所有节点,不需要满足窗口。
答案 0 :(得分:0)
有了你写的所有内容,似乎你唯一的问题是:"我应该循环还是应该递归?"根据您的需要,以最容易阅读和维护的方式(或者性能是您的最高优先级,以较高的性能为准)。
您正在处理链接列表。我建议简单地循环,而不是递归。 (如果你正在处理一棵树,那将是一个不同的故事。)在任何一种情况下,你都可以通过做某种形式的记忆来找到一种节省大量计算的方法。如果您的窗口涉及左右数百个节点,则可以存储节点 n 的大部分密度计算,并且几乎所有节点都可以重复使用 n + 1 。在你开始讨论之前,我先测试一下非记忆版本,然后看看它是否具有足够的性能。
可以帮助您删除边缘情况的一种设计模式是具有Null节点:
Node nullNodeBeginning = new nullNode(length=0, weight=0);
nullNodeBeginning.prev = nullNodeBeginning;
Node nullNodeEnding = new nullNode(length=0, weight=0);
nullNodeEnding.next = nullNodeEnding;
如果您将nullNodeBeginning
添加到链接列表的开头并将nullNodeEnding
添加到链接列表的末尾,则实际上会有一个无限链接列表。然后你的逻辑变成了:
还有其他方法可以做到这一点(这需要保持所有节点的长度),但是通过使用nullNode限制列表,您应该能够避免除了节点不足之外的所有特殊情况对于窗口",并使你的逻辑更清洁。