【Leetcode】编程实践学习Task01:分治

Task 01:分治

分治算法

  • 分治算法的主要思想
    将原问题递归地分成若干个子问题,直到子问题满足边界条件 ,停止递归。将子问题逐个击破(一般是同种方法),将已经解决的子问题合并,最后,算法会层层合并得到原问题的答案。
  • 分治算法的步骤:
    1.分: 递归地将问题分解为各个性质相同的、相互独立的子问题;
    2.治: 将这些规模更小的子问题逐个击破;
    3.合: 将已解决的子问题 逐层合并,最终得出原问题的解;

leetcode 169. 多数元素

题目描述

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2

分析
  1. 分:子问题为每一个独立的数字,递归地将原数组二分为左区间与右区间,直到最终的数组只剩下一个元素
  2. 治:长度为 1 的子数组中唯一的数显然是众数,所以每个子问题的众数就是本身
  3. 合:如果子数组只含一个数字直接返回;如果左右区间的众数相同,返回该众数;如果他们的众数不同,返回出现次数更多的那个众数。
C++代码
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        if(nums.size()==1)
            return nums[0];
        vector<int> left,right;
        int left_n,right_n;
        int n = nums.size();
        for(int i=0;i<n/2;i++)
            left.push_back(nums[i]);
        for(int i=n/2;i<n;i++)
            right.push_back(nums[i]);
        left_n = majorityElement(left);
        right_n = majorityElement(right);
        if(left_n==right_n)
            return left_n;
        if(count(nums.begin(),nums.end(),left_n)>count(nums.begin(),nums.end(),right_n))
            return left_n;
        else
            return right_n;
    }
};

leetcode 53. 最大子序和

题目描述

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大为 6。

进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

分析

将数组划分为左右两个区间,最大子序列要么在左区间,要么在右区间,要么在左右区间连接处,分别计算这三种情况下的最大子序和,返回最大的那一个。

C++代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size()==1)
            return nums[0];
        int n = nums.size();
        vector<int> left,right;
        int l,r;
        for(int i=0;i<n/2;i++)
            left.push_back(nums[i]);
        for(int i=n/2;i<n;i++)
            right.push_back(nums[i]);
        l = maxSubArray(left);
        r = maxSubArray(right);
        
        int max_l,max_r,tot;
        max_l = nums[n/2-1];
        tot=0;
        // 左区间从右到左累加
        for(int i=n/2-1;i>=0;i--)
        {
            tot+=nums[i];
            max_l = max(tot, max_l);
        }
        max_r = nums[n/2];
        tot=0;
        for(int i=n/2;i<n;i++)
        {
            tot+=nums[i];
            max_r = max(tot, max_r);
        }
        if(l<r)
            return max(r, max_l+max_r);
        else
            return max(l, max_l+max_r);
    }
};

leetcode 50. Pow(x,n)

题目描述

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1: 输入: 2.00000, 10 输出: 1024.00000

示例 2: 输入: 2.10000, 3 输出: 9.26100

示例 3: 输入: 2.00000, -2 输出: 0.25000

分析
  1. 递归终止条件:x的零次幂为1;
  2. 如果幂级数小于零,x要转化为倒数,同时幂级数改成正数;
  3. 如果是偶次幂,相当于x的平方的n/2次幂,如果是奇次幂,相当于x*x^(n-1),其中求幂操作可递归。
C++代码
class Solution {
public:
    double myPow(double x, long long n) {
        if(n==0)
            return 1;
        if(n<0){
            x = 1.0/x;
            n = -n;
        }
        if(n%2==0)
            return myPow(x*x, n/2);
        else{
            double tmp = x * myPow(x,n-1);
            return tmp;
        }      
    }
};

你可能感兴趣的:(C++)