Divide and Conquer (1) -- Kth Largest Element in an Array,Different Ways to Add Parentheses

Kth Largest Element in an Array

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.

Note: 
You may assume k is always valid, 1 ≤ k ≤ array's length.

解法1:快排。由于我们只关心第k大的数字,因此第k个数字之前是不需要排序;即在使用快排时,只需要对包含第k个数字的序列进行排序。

class Solution {
public:
    //插入排序,在元素小于20时,插入通常优于快排
    void insertSort(vector<int>& a,int left, int right){
        for(int i = left + 1; i <= right; i++){
         int tmp = a[i];
         int j = i;
         for(; j > left && a[j - 1] > tmp; j--){
            a[j] = a[j-1];
         }
         a[j] = tmp;
        }
    }
    //找到三位中值的同时将三个数放在正确的位置
    int median3(vector<int>& a, int left, int right){
        int mid = (left + right) / 2;
        if(a[left] > a[mid])    
            swap(a[left], a[mid]);
        if(a[left] > a[right])
            swap(a[left], a[right]);
        if(a[mid] > a[right])
            swap(a[mid], a[right]);
        swap(a[mid], a[right-1]);  //放在末尾的前一位
        return a[right-1];
    }
    
    //一次快排将一个元素放置在自己的位置
    void quickSort(vector<int>& a, int left, int right, int k){
        int cutoff = 3;
        //只有当元素个数大于等于3时才使用快排
        if (right - left + 1 >= cutoff) {
            int pivot = median3(a, left, right);
            int i = left, j = right - 1;
            while (true) {
                while(a[++i] < pivot);  //这里要注意a[i] = a[j] = pivot的情况,总之要先进行加减操作
                while(a[--j] > pivot);
                if(i < j) swap(a[i], a[j]);
                else break;
            }
            swap(a[i], a[right-1]); //i是pivot的正确位置
            if (i == k - 1) return;
            else if(i < k - 1)   //由于找的是第smallK小(第K大),所以有一部分是不需要排序的
                quickSort(a, i + 1, right, k);
            else
                quickSort(a, left, i - 1, k);
        }
        else
            insertSort(a, left, right);
    
    }

    int findKthLargest(vector<int>& nums, int k) {
        int smallK = nums.size() - k + 1; //转换为第smallK小
        quickSort(nums, 0, nums.size()-1, smallK);
        return nums[smallK-1];
    }
};


Different Ways to Add Parentheses

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +- and *.


Example 1

Input: "2-1-1".

((2-1)-1) = 0
(2-(1-1)) = 2

Output: [0, 2]


解法1:递归。关键是弄清如何进行分割。

    vector<int> diffWaysToCompute(string input){
        int n = input.size();
        vector<int> total;
        for(int i = 0; i < n; i++){
            char c = input[i] ;
            //遇到运算符之后将字符串分开
            if(c == '*' || c == '+' || c == '-'){
                vector<int> result1 = diffWaysToCompute(input.substr(0, i));
                vector<int> result2 = diffWaysToCompute(input.substr(i+1));
                for (auto n1 : result1) {
                    for (auto n2 : result2) {
                        if (c == '+')
                            total.push_back(n1 + n2);
                        else if (c == '-')
                            total.push_back(n1 - n2);
                        else
                            total.push_back(n1 * n2);
                    }
                }
            }
        }
        // if the input string contains only number
        if (total.empty())
            total.push_back(atoi(input.c_str()));
        return total;
    }

改进:使用map<string, vector<int> >记录已计算过的结果

    vector<int> diffWays(string input, unordered_map<string, vector<int> >& waysMap){
        if(waysMap.find(input) != waysMap.end()) return waysMap[input]; 
        int n = input.size();
        vector<int> total;
        for(int i = 0; i < n; i++){
            char c = input[i] ;
            //遇到运算符之后将字符串分开
            if(c == '*' || c == '+' || c == '-'){
                string s1 = input.substr(0, i);
                string s2 = input.substr(i+1);
                vector<int> result1 = diffWays(s1, waysMap);
                vector<int> result2 = diffWays(s2, waysMap);
                for (auto n1 : result1) {
                    for (auto n2 : result2) {
                        if (c == '+') total.push_back(n1 + n2);
                        else if (c == '-') total.push_back(n1 - n2);
                        else total.push_back(n1 * n2);
                    }
                }
            }
        }
        // if the input string contains only number
        if (total.empty()) total.push_back(atoi(input.c_str()));
        waysMap[input] = total;
        return total;
    }
    
    vector<int> diffWaysToCompute(string input){
        unordered_map<string, vector<int> > waysMap;
        return diffWays(input, waysMap);
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值