分治法学习笔记
目录1,什么是分治法
字面意思,就是将一个大问题分解为若干个小问题求解,然后再用小问题的解组成大问题的解。
2,什么时候使用分治法
当一个问题明显可以分为问题相同,但是规模更小的子问题,并且子问题容易求解的时候,考虑分治法。
3,分治法的解题步骤
分治法有比较通用的套路:
- 求解边界条件,即最小规模的子问题直接算出
- 将大问题分解为小问题,通常用都是一分为二,然后调用自己求解小问题
- 将小问题的解组合得出大问题的解
4,分治法与动态规划的异同
相同点:都是将大问题分解为更小规模的子问题求解
不同点:
- 分治法的子问题通常不具有重叠的子结构,而且分治法通常使用递归算法
- 动态规划的子问题具有重叠的子结构,且动态规划通常使用数组存储子问题的答案,并且使用迭代算法
5,例题
来实践一下:
例题:
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例一:
输入:nums = [3,2,3]
输出:3
解题思路:
1,大小为n的数组求多数元素不好求,但是大小为1的数组的多数元素好求。
2,因此,我们使用分治法,将大小为n的数组分解为两个大小为n/2的数组,求出两个数组的多数元素,然后合并。
3,当两个数组的多数元素相等时,总的多数元素即为该元素;
当两个数组的多数元素不相等时,遍历这两个数组,分别求出两个候选多数元素的数量,谁的数量多即为总的多数元素。
代码:
class Solution {
public int majorityElement(int[] nums) {
int len = nums.length;
return fun(nums, 0, len-1);
}
public int fun(int[] nums, int left, int right){
if (left == right)
return nums[left];
int mid = (left+right)/2, v1=fun(nums,left,mid), v2=fun(nums,mid+1,right);
if (v1 == v2)
return v1;
return merge(nums,v1, v2, left, right);
}
public int merge(int[] nums, int v1, int v2, int left, int right){
int count1=0, count2=0;
for(int i = left; i <= right; i++){
if (nums[i] == v1)
count1++;
if (nums[i] == v2)
count2++;
}
return count1 >= count2 ? v1 : v2;
}
}
标签:元素,nums,int,分治,笔记,学习,数组,left
From: https://www.cnblogs.com/wyh-s/p/17090639.html