ThreeSum 算法
题目: 统计一个数组中所有和为0的三整数元组的数目,这个问题是类似三点共线或者三线共面问题的简化版。1
算法1 (暴力求解)
func ThreeSum(a []int) int {
	N := len(a)
	count := 0
	for i := 0; i < N; i++ {
		for j := i + 1; j < N; j++ {
			for k := j + 1; k < N; k++ {
				if (a[i] + a[j] + a[k]) == 0 {
					count++
				}
			}
		}
	}
	return count
}
非常容易的看到其算法复杂度为$N^3$。
算法2 优化算法
首先将a排序,算法思想是将前两个数字相加a[i]+a[j],然后在a中寻找这两个数字和的负数,也就是-a[i]-a[j],如何找到了,且下标大于j,则计数加1。
func ThreeSumFast(a []int) int {
	sort.Ints(a)  // 排序
	N := len(a)
	count := 0
	for i := 0; i < N; i++ {
		for j := i + 1; j < N; j++ {
			if BinarySearch(-a[i]-a[j], a) > j { //二分查找
				count++
			}
		}
	}
	return count
}
这个算法的时间复杂度是$N^2logN$,在我的笔记本上对1000个数字进行处理,运行的时间如下:
ThreeSum took 254.934984ms
ThreeSumFast took 18.43887ms
二分查找算法
unc BinarySearch(key int, a []int) int {
	lo := 0
	hi := len(a) - 1
	var mid int
	for lo <= hi {
		mid = lo + (hi-lo)/2
		if key < a[mid] {
			hi = mid - 1
		} else if key > a[mid] {
			lo = mid + 1
		} else {
			return mid
		}
	}
	return -1
}
- 学习来源:http://algs4.cs.princeton.edu/14analysis/,代码参见:GitHub ↩