您可以通过先对数组进行排序,然后使用哈希值查找(下面的
方法1)或有关排序数组的巧妙排除来过滤重复颜色对象,从而避免暴力
O(n^2)
嵌套循环(和枚举)解决方案。
还要注意类
类型命名约定(
CamelCase
):因此使用
Foo
而不是
foo
。
免责声明:不要盯着下面的渐近复杂性符号看得眼花缭乱,因为
早期优化根据程序的上下文和预期使用领域,通常是一种错误。我仅包含它们以便比较不同的方法。选择您认为最有意义的方法。
方法1
最坏情况...
时间复杂度: O(n log n)
空间复杂度: O(n)
其中空间复杂度是指超过分配给最终结果的数组所使用的空间。
- 让
Foo
符合Hashable
(让hashValue
与.color
属性相关联)。
- 按照大小递减的顺序对
Foo
实例数组进行排序(.size
属性)。
- 使用符合
Hashable
的实现,通过在Foo:Bool
字典中迅速使用O(1)
哈希值查找现有颜色来过滤已排序的数组中的每种颜色的第一个出现。从Airspeed Velocity在以下答案中的评论中改编而来。
方法二(由Nikolai Ruhe提出):
最坏情况下...
时间复杂度:O(n log n)
空间复杂度:O(1)
- 按颜色(主要)和大小(次要)对数组进行排序。
- 过滤已排序的数组,找出与它们前面的元素颜色不同的元素。
对于第三种方法(可能是此应用程序的最佳方法),
请参见下面 Nikolai Ruhe 的答案,介绍了一种具有
O(n)
/
O(n)
时间/空间最坏情况复杂度的方法。
实现
[这一步仅适用于方法1] 使 Foo
符合 Hashable
和 Equatable
:
class Foo : Hashable {
var color: String
var size: Int
var shape: String
init(color:String, size:Int, shape:String){
self.color = color
self.size = size
self.shape = shape
}
var hashValue: Int {
return color.hashValue
}
}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.color == rhs.color
}
为即将介绍的过滤方法设置一个示例:
var array = [Foo]()
array.append(Foo(color: "Blue", size: 2, shape: "Round"))
array.append(Foo(color: "Red", size: 3, shape: "Square"))
array.append(Foo(color: "Blue", size: 5, shape: "Round"))
array.append(Foo(color: "Yellow", size: 1, shape: "Triangle"))
array.append(Foo(color: "Blue", size: 1, shape: "Hexagon"))
按照您的规格筛选:
var addedDict = [Foo:Bool]()
var arrFiltered = array.sort{ $0.0.size > $0.1.size }
.filter {addedDict.updateValue(true, forKey: $0) == nil }
var previousColor: String?
let arrFiltered = array.sort{ $0.color == $1.color ? $0.size > $1.size : $0.color < $1.color }
.filter{ if $0.color != previousColor { previousColor = $0.color; return true }; return false }
结果:
for bar in arrFiltered {
print(bar.color, bar.size)
}
这个解决方案中(对于两种方法而言),排序步骤是主要的步骤。从
swift/stdlib/public/core/Sort.swift.gyb 可以看出,Swift 使用
introsort(具体来说是介绍排序和
插入排序的混合体)进行排序,在最坏情况下运行时间为
O(n log n)
。