Lintcode - 中位数

class Solution {
public:
#if 0
    /*
     * @param nums: A list of integers
     * @return: An integer denotes the middle number of the array
     */
    int median(vector<int> &nums) {
        // write your code here
        
        int k = (nums.size() + 1) / 2;// support add and noun
        priority_queue<int> que;
        int len = nums.size();
        for(int i = 0; i < len; i ++) {
            if(que.size() == k) { // 当queue到到达了半数的时候
                if(nums[i] < que.top()) {
                    que.pop();
                    que.push(nums[i]);
                }
            }else {
                que.push(nums[i]); // insert it directly
            }
        }
        return que.top();
    }
#endif
#if 0
    /*
     * @param nums: A list of integers
     * @return: An integer denotes the middle number of the array
     */
    typedef multiset<int, greater<int>> intSet;
    typedef multiset<int, greater<int>>::iterator setIterator; 
    int median(vector<int> &nums) {
        // write your code here
        int k = (nums.size() + 1)/2;
        intSet st;
        int len = nums.size();
        for (int i = 0; i < len; i++) {
            if (st.size() == k) {
                setIterator iterGreatest = st.begin();
                if (nums[i] < *st.begin()) {
                    st.erase(iterGreatest);
                    st.insert(nums[i]);
                }
            } else {
                st.insert(nums[i]);
            }
        }
        return *st.begin();
    }
#endif

#if 1
    /*
     * @param nums: A list of integers
     * @return: An integer denotes the middle number of the array
     */
    int median(vector<int> &nums) {
        // write your code here
        int k = (nums.size() + 1)/2 - 1;
        int l = 0;
        int r = nums.size() - 1;
        
        //int index = LomutoPartition(nums, l, r);
        int index = HoarePartition(nums, l, r);
        while (index != k) {
            if (index > k) {
                r = index - 1;
                //index = LomutoPartition(nums, l, r);
                index = HoarePartition(nums, l, r);
            } else {
                l = index + 1;
                //index = LomutoPartition(nums, l, r);
                index = HoarePartition(nums, l, r);
            }
        }
        
        return nums[index];
    }
    // 第一个元素作为中轴,进行划分  
    int HoarePartition(vector<int> &A, int l, int r) {  
        int p = A[l];//dealPivot(A, l, r);//RandomInRange(A, l, r);  
        int i = l;  
        int j = r+1;  
          
        do {  
            do {  
                i++;  
            } while (A[i] < p);  
              
            do {  
                j--;  
            } while (A[j] > p);  
              
            swap(A[i], A[j]);  
        } while (i < j);  
        swap(A[i], A[j]); //当i>=j撤销最后一次交换  
        swap(A[l], A[j]);  
          
        return j;  
    }
    // 第一个元素作为中轴,进行划分  
    int dealPivot(vector<int> &A, int l, int r) {  
        int mid = (l + r) / 2;  
        if (A[l] > A[mid]) {  
            swap(A[l], A[mid]);  
        }  
        if (A[l] > A[r]) {  
            swap(A[l], A[r]);  
        }  
        if (A[r] < A[mid]) {  
            swap(A[r], A[mid]);  
        }  
        // 放到最左边  
        swap(A[l], A[mid]);  
        return A[l];  
    }
    // l和r中间的随机数作为中轴  
    int RandomInRange(vector<int> &A, int l,int r) {  
        srand ( time(NULL) );  
        int num = rand() % (r-l+1) + l;  
        // 放到最左边  
        swap(A[l], A[num]);  
        return A[l];  
    }
    //
    // 第一个元素作为中轴,进行划分,从左到右进行单项扫描划分  
    int LomutoPartition(vector<int> &A, int l, int r) {  
        int p = A[l];  
        int s = l;  
          
        for (int i=l+1; i<=r; i++) {  
            if (A[i] < p) {  
                s++; // 先增加s的右边  
                swap(A[s], A[i]);// 交换到最右边的s位置  
            }  
        }  
          
        swap(A[l], A[s]);  
        return s;  
    }
#endif
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值