53.最大子数组和
将原数组划分为左右两个数组后,原数组中拥有最大和的连续子数组的位置有三张情况。
情况1. 原数组中拥有最大和的连续子数组的元素都在左边的子数组中。
情况2. 原数组中拥有最大和的连续子数组的元素都在右边的子数组中。
情况3. 原数组中拥有最大和的连续子数组的元素跨越了左右数组。
分别求出,3中情况的最大和,取最大,就是原数组的连续子数组的最大和。
所以在具体考虑的时候需要将无法递归得到结果的中间那个最大值串的结果也算出来参与左侧、右侧值得比较。所以对中间值的取法有很多种;
class Solution {
public int getMax(int[] nums, int low, int high) {
// 如果子数组只有一个元素,这个元素就是子树组的最大和。
if (low == high) {
return nums[low];
}
int mid = low + (high - low) / 2;
// 求左数组的最大和
int leftMax = getMax(nums, low, mid);
// 求右数组的最大和
int rightMax = getMax(nums, mid + 1, high);
// 求跨越情况的最大和
int crossMax = getCrossMax(nums, low, mid, high);
// 返回最大
return Math.max(Math.max(leftMax, rightMax), crossMax);
}
// 求跨越情况的最大和
public int getCrossMax(int[] nums, int low, int mid, int high) {
//初始化
int lowSum = 0;
int lowMax = nums[mid];
int highSum = 0;
int highMax = nums[mid];
// 从中间向左走,一直累加,每次累计后都取最大值,最后得到的就是从中间向左累加可得到最大和
for (int i = mid; i >= low; i--) {
lowSum += nums[i];
lowMax = Math.max(lowSum, lowMax);
}
// 从中间向右走,一直累加,每次累计后都取最大值,最后得到的就是从中间向右累加可得到最大和
for (int i = mid; i <= high; i++) {
highSum += nums[i];
highMax = Math.max(highSum, highMax);
}
return highMax + lowMax - nums[mid];
}
public int maxSubArray(int[] nums) {
return getMax(nums, 0, nums.length - 1);
}
}
169. 多数元素
题解传送门
class 多数元素fenzhi {
public int count(int[] nums, int target, int start, int end){//计数target有多少个函数
int count = 0;
for (int i = start; i <= end; i++) {
if (nums[i] == target){
count ++;
}
}
return count;
}
public int majorityElementRec(int[] nums, int start, int end){
if(start == end){
return nums[start];
}
int mid = start + (end - start) / 2;
int left = majorityElementRec(nums, start, mid);
int right = majorityElementRec(nums, mid + 1, end);
if(left == right){
//两边都相等的话,就随便返回一个
return left;
}
//到这里就说说明,left和right不相等,有分歧;
//所以合并left和right数组,再来看谁最多;
int leftCount = count(nums, left, start, end);
int rightCount = count(nums, right, start, end);
return leftCount > rightCount ? left: right;
}
public int majorityElement(int[] nums) {
return majorityElementRec(nums, 0, nums.length-1);
}
}