暴力算法的优化

对于一些暴力循环嵌套的算法,例如抽签,从n个数里依次取4个数,每次取完皆放回。求取完4次后的数字是否有可能等于某个数。即a[i] + a[j] + a[k] + a[g] == m;
这样暴力的话就用4个for循环嵌套枚举每一种相加的和的可能性外加判断语句。但是这样复杂度是On^4,明显太大。
初步优化:那么想到,由于n个数是给定的,而且每次取的数字都在这个给定的数组里取,那么我们尝试把n^4给拆分掉,我们可以把求最后一个数的那个循环改写成二分查找,判断的数为m - a[i] - a[j] - a[k] 与目标区间的a[mid]相比较大小,最后判断得到的a[l]是否满足我们的需要。
对于这种优化,因为二分查找的前提是sort排序,故复杂度为:
排序O(nlogn)
循环O(n^3logn)
只看最大值,那就是O(n^3logn),比原先的O(n^4)小了很多,但还是不够。再看。

第二次优化:既然有了二分查找的思路,那么我们可以继续思考,对于循环所需要的复杂度,是否可以继续拆分。没错,是可以的,我们这次把4个循环里的里面两个循环都拿出来,用二分查找判断。但是这次并不能直接用,因为没有现成的a[k] + a[g]的数组,所以要先枚举所有的a[k] + a[g]情况并保存在新数组b[k * n + g]里;然后再对数组b排序。
接下来就跟第一种方案一样,只是查找的判断改为m - a[i] - a[j] 与 b[mid]比较。最后判断的条件改为m - a[i] - a[j] == b[l];
对于这种优化,复杂度为:
枚举新数组:O(n^2)
排序: O(n^2log(n^2))
循环:O(n^2log(n^2))
再一次大大缩减了复杂度。。可见,善用二分判断查找答案,是一种很快速的方法。

你可能感兴趣的:(暴力算法的优化)