9.21Leetcode記錄

一、數據流中的中位數

題目

如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。

例如,

[2,3,4] 的中位數是 3

[2,3] 的中位數是 (2 + 3) / 2 = 2.5

設計一個支持以下兩種操作的數據結構:

void addNum(int num) - 從數據流中添加一個整數到數據結構中。
double findMedian() - 返回目前所有元素的中位數。

示例 1:

輸入:
["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]
[[],[1],[2],[],[3],[]]
輸出:[null,null,null,1.50000,null,2.00000]

示例 2:

輸入:
["MedianFinder","addNum","findMedian","addNum","findMedian"]
[[],[2],[],[3],[]]
輸出:[null,null,2.00000,null,2.50000]

限制:

  • 最多會對 addNum、findMedian 進行 50000 次調用。

題解

需要用到優先隊列的思想,分別記錄大於中位數queMax和小於等於中位數queMin的數。

當累計添加的數爲奇數時,queMin 中的數的數量比queMax 多一個,此時中位數爲 queMin 的隊頭。

當累計添加的數爲偶數時,此時中位數爲qunMin和queMax的隊頭的平均值。

當區要添加一個數時,進行討論:

①num<=max(queMin)

num小於中位數,將其添加到queMin,新的中位數將小於等於原來的中位數,因此需要將queMin中的最大數移到queMax中。

②num>max(queMin)

num大於中位數,將其添加到queMax,新的中位數大於原來的,需要將queMax中的最小數移到queMin中。

特殊:注意當新添加一個數時,默認到queMin隊列中。

代碼

class MedianFinder {
public:
    /** initialize your data structure here. **/

    priority_queue<int, vector<int>, less<int>> queMin;
    priority_queue<int, vector<int>, greater<int>> queMax;
    
    MedianFinder() {
       
    }
    
    void addNum(int num) {
        if(queMin.empty()||num<=queMin.top())
        {
            queMin.push(num);
            if(queMax.size()+1<queMin.size())
            {
                queMax.push(queMin.top());
                queMin.pop();
            }
        }
        else
        {
            queMax.push(num);
            if(queMin.size()<queMax.size())
            {
                queMin.push(queMax.top());
                queMax.pop();
            }
        }
        
    }
    
    double findMedian() {
        if(queMin.size()>queMax.size())
            return double(queMin.top());
        else
            return (queMin.top()+queMax.top())/2.0;
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

 二、把數組排成最小的數

題幹:

輸入一個非負整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。

示例 1:

輸入: [10,2]
輸出: "102"

示例 2:

輸入: [3,30,34,5,9]
輸出: "3033459"

提示:

0 < nums.length <= 100
說明:

輸出結果可能非常大,所以你需要返回一個字符串而不是整數
拼接起來的數字可能會有前導 0,最後結果不需要去掉前導 0

題解

對數組進行排序,排序時進行比較,選擇兩個數加起來較小的一方。

代碼

class Solution {
public:
    string minNumber(vector<int>& nums) {

        vector<string> strs;
        for(auto num:nums)
        {
            strs.push_back(to_string(num));
        }
        sort(strs.begin(),strs.end(),comp);
        string ans;
        for(auto str:strs){
            ans+=str;
        }
        return ans;
    }

    static bool comp(string a,string b)
    {
        return a+b<b+a;
    }


};

三、連續子數組的最大和

題幹

輸入一個整型數組,數組中的一個或連續多個整數組成一個子數組。求所有子數組的和的最大值。

要求時間複雜度爲O(n)。

示例1:

輸入: nums = [-2,1,-3,4,-1,2,1,-5,4]
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。

提示:

  • 1 <= arr.length <= 10^5
  • -100 <= arr[i] <= 100

題解

對於數組中的每個數,找出以他爲終點的子數組最大和,因此只需將:目前的數+前一個數的子數組最大和>目前的數,則目前的數爲加和之後的。

對整個數組遍歷一遍,即可求出每個位置上的以他爲終點的子數組的最大和。

代碼

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
    int a_max=nums[0];
    int maxn=a_max;

    for(int i=1;i<nums.size();i++)
    {
        if(nums[i]+nums[i-1]>nums[i])
        {
            nums[i]=nums[i]+nums[i-1];
            maxn=max(nums[i],maxn);
        }
        else
        {
            maxn=max(nums[i],maxn);
        }
    }
    return maxn;

    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章