Leetcode 分治法

分治法

分治法的思想是将问题分而治之:
1. 将问题分成小问题
2. 分治完毕后,触发递归中的结束判定语句
3. 将分治的结果 合并一起

求majority

题目

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

解析

因为majority在数组中出现大于 n/2 次,因此可以将数组分半,求出左半部分的大多数和右半部分的大多数,这样就可以将问题分而治之。

在merge环节中,因为数组只能够返回大多数的元素,而不是其次数,所以,merge时需要比较两者的次数,返回较大的那个。

源代码

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        /*采用分治法
            将数组分成left 和 right两边,分别计算出两边的me
            合并时,返回较大的那个数
            */
        return majorCompute(nums, 0, nums.size() - 1);
    }

    int majorCompute(vector<int>& nums, int left, int right) {
        if (left >= right)
            return nums[left];
        int mid = (left + right) / 2;
        int l = majorCompute(nums, left, mid);
        int r = majorCompute(nums, mid + 1, right);
        if (l == r)
            return l;
        else 
            return count(nums.begin() + left, nums.begin() + mid, l) > count(nums.begin() + mid, nums.begin() + right, r)?  l:  r;
    }

};

求第k大的数

题目

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

解析

这道题如果用最优的排序方法,时间复杂度是可以到达O(nlogn)的,比如堆排序。

但求k大问题是一个典型的运用分治思想可以解决的问题。

  1. 随机在数组中抽取一个数作为v,将原数组分成三份,小于v(Sl),等于v(Sv),大于v的(Sg)。
  2. 若求的k值大于 |Sg| ,那么要求的值必定不在Sg中。
    若求的k值大于 |Sg|+|Sv| ,那么求的第k大必定不在Sv中。
    其余情况第k大只可能在Sl中。
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        if (nums.size() == 1)
            return nums[0];
        vector<int> Sl, Sv, Sg;
        //用数组中间位置的数作为v
        int v = nums[nums.size() / 2];
        //分类
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] == v)
                Sv.push_back(nums[i]);
            else if (nums[i] < v)
                Sl.push_back(nums[i]);
            else 
                Sg.push_back(nums[i]);
        }
        if (k <= Sg.size())
            return findKthLargest(Sg, k);
        else if (k <= Sg.size() + Sv.size())
            return v;
        else 
            return findKthLargest(Sl, k - Sg.size() - Sv.size());


        // sort(nums.begin(), nums.end());
        // return nums[nums.size() - k];
    }
};

你可能感兴趣的:(leetcode,解题思路)