在数组中给出边的唯一三角形的数量

时间:2013-07-05 12:08:04

标签: algorithm

我想通过强力(O(N ^ 3)或递归bactracking)找到“唯一”三角形的最大数量(每个数组元素只能使用一次)。应该采取什么方法?

2 个答案:

答案 0 :(得分:1)

首先假设所有边的长度都是正整数。 (对于实数,间隔是半开 - 半 - 关闭并使其更加混乱。)

基本上,如果我们找到一种有效的方法来获取每个[a,b]范围0<=a<=b范围内长度的边数,我们可以将其处理为:

    edgeList = sort edgeList by length ascending order
    foreach ( edge1 in edgeList )
        foreach ( edge2 in edgeList where [edge2 >= edge1] )
            answer = answer + count_edge_number ( edge2 , edge1+edge2-1 );
    return answer;

因此我们只需要这样的方式。要做到这一点,您只需按长度按升序对边进行排序,使用二进制搜索来查询相关区间的下限和上限的索引(订阅)。 (也就是说,对于任何[a,b],使用二进制搜索来查找i最大element[i]<a,最小j element[j]<=b)。这适用于O(logN)

因此,您的任务可以在O(N^2LogN)中实现,远远优于草书O(N^3)

答案 1 :(得分:0)

创建一个地图(hashmap应该没问题),端点映射到side。所以每一方都有2个条目 - 每个端点一个。现在,您可以从任何给定的终点开始有效地查找所有方面。

一些基本的伪代码:

// map[X] is all unused sides with X as end-point
// markAsUsed should also remove the side from the map
// markAsUnused should also add the side to the map

// initial function call for any unused side
backTrackFunction(anyUnusedSide)

backTrackFunction(side AB)
  if map.isEmpty
    Found a solution.
  markAsUsed(AB)
  for each side AC in map[A]
    if map[C].contains(CB)
      // AB, CB and AC form a triangle
      markAsUsed(CB)
      markAsUsed(AC)
      backTrackFunction(anyUnusedSide)

      // Backtrack
      markAsUnused(CB)
      markAsUnused(AC)

以上可能存在一些问题,但它只是一个起点。