剑指offer-排序

1.数组中重复的数字

使nums[i] = i;交换不动了就是重复的数字。

    int duplicate(vector<int>& nums) {
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] < 0 or nums[i] >= nums.size())
                return -1;
        }
        for (int i = 0; i < nums.size(); ++i) {
            while (nums[i] != i and nums[i] != nums[nums[i]]) {
                swap(nums[i], nums[nums[i]]);
            }
            if (nums[i] != i and nums[i] == nums[nums[i]])
                return nums[i];
        }
        return -1;
    }

2.数组中的逆序对

归并排序。

class Solution {
    using LL = long long;
    const int MOD = 1000000007;
    vector<int> temp;
    LL mergeSort(vector<int>& nums, int l, int r){
        if(l >= r) return 0;
        int mid = (l + r) >> 1;
        LL res = mergeSort(nums, l, mid) + mergeSort(nums, mid + 1, r);
         
        int k = 0, i = l, j = mid + 1;
        while(i <= mid and j <= r){
            if(nums[i] <= nums[j]) temp[k++] = nums[i++];
            else {
                temp[k++] = nums[j++];
                res += mid - i + 1;
            }
        }
        while(i <= mid) temp[k++] = nums[i++];
        while(j <= r) temp[k++] = nums[j++];
        for(int i = l, j = 0; i <= r; ++i, ++j) nums[i] = temp[j];
        return res % MOD;
    }
public:
    int InversePairs(vector<int> data) {
        if (data.size() == 1) return 0;
        temp = vector<int>(data.size());
        return mergeSort(data, 0, data.size() - 1);
    }
};

3.最小的K个数

快排 快排返回的数字l是一个下标,[0, l]之间就是最小的l + 1个数(该区间无序)。

class Solution {
    int quickSort(vector<int>& nums, int l, int r, int k) {
        if (l >= r) return l;
        int i = l - 1, j = r + 1, x = nums[l + r >> 1];
        while (i < j) {
            do i++; while (nums[i] < x);
            do j--; while (nums[j] > x);
            if (i < j) swap(nums[i], nums[j]);
        }
        int len = j - l + 1;
        if (k <= len) return quickSort(nums, l, j, k);
        else return quickSort(nums, j + 1, r, k - len);
    }
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        if (k == 0 or input.empty()) return {};
        auto end = quickSort(input, 0, input.size() - 1, k);
        return vector<int>(input.begin(), input.begin() + end + 1);
    }
};

堆排 使用make_heap函数和仿函数greater<int>()建小根堆。

    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        int n = input.size();
        if (n == 0) return {};
        vector<int> res(k);
        for (int i = 0; i < k; ++i) {
            make_heap(input.begin(), input.begin() + n, greater<int>());
            res[i] = input[0];
            swap(input[0], input[--n]);
        }
        return res;
    }

4.数据流中的中位数

上面是一个小根堆,下面是一个大根堆。

class Solution {
    priority_queue<int> maxQ;
    priority_queue<int, vector<int>, greater<int>> minQ;
public:
    void Insert(int num) {
        maxQ.push(num);
        if (!minQ.empty() and maxQ.top() > minQ.top()) {
            int maxV = maxQ.top(), minV = minQ.top();
            maxQ.pop(), minQ.pop();
            maxQ.push(minV);
            minQ.push(maxV);
        }
        if (maxQ.si***Q.size() + 1) {
            minQ.push(maxQ.top());
            maxQ.pop();
        }
    }

    double GetMedian() { 
        if ((maxQ.si***Q.size()) & 1) return maxQ.top();
        else return (maxQ.top() + minQ.top()) / 2.0;
    }
};
全部评论

相关推荐

Noob1024:一笔传三代,人走笔还在
点赞 评论 收藏
分享
oppo 应用软开 22*15+0.5*12
拿到了ssp完美:真的坎坷,但是你至少拿到这么多offer了!
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务