分治法的核心思想就是分而治之,具体来说,它先将一个难以直接解决的大问题,分割成一些可以直接解决的小问题。如果分割后的问题仍然无法直接解决,那么就继续递归地分割,直到每个小问题都可解。
分治法的使用方法
几个特征
1)难度在降低,即原问题的解决难度,随着数据的规模的缩小而降低。这个特征绝大多数问题都是满足的。
2)问题可分,原问题可以分解为若干个规模较小的同类型问题。这是应用分治法的前提。
3)解可合并,利用所有子问题,可合并出原问题的解。这个特征很关键,能否利用分治法完全取决于这个特征。
4)相互独立,各个子问题之间相互独立,某个子问题的求解不会影响到另一个问题。如果子问题之间不独立,则分治法需要重复地解决公共的子问题,造成效率底下的结果。
分治法在每轮递归上,都包含了分解问题、解决问题和合并问题这3个步骤。
二分查找:
func main() { targetNum := 8 arr := [10]int{1,2,3,4,5,6,7,8,9,10} var middle int var low int var high = len(arr) - 1 isfind := 0 for low < high { middle = (high + low) / 2 if arr[middle] == targetNum { fmt.Println("找到了: ", arr[middle], middle) isfind = 1 break } else if arr[middle] > targetNum { high = middle - 1 } else { low = middle + 1 } } if isfind == 0 { fmt.Println("没有找到") } }
1.二分查找的时间复杂度是 O(logn),这也是分治法普遍具备的特性。当你面对某个代码题,而且约束了时间复杂度是 O(logn) 或者是 O(nlogn) 时,可以想一下分治法是否可行。
2.二分查找的循环次数并不确定。一般是达到某个条件就跳出循环。因此,编码的时候,多数会采用 while 循环加 break 跳出的代码结构。
3.二分查找处理的原问题必须是有序的。因此,当你在一个有序数据环境中处理问题时,可以考虑分治法。相反,如果原问题中的数据并不是有序的,则使用分治法的可能性就会很低了。