Leetcode493——Reverse Pairs

来源:互联网 发布:linux ssh配置文件路径 编辑:程序博客网 时间:2024/06/18 01:24

垃圾如我,先mark一下吧,听说树状数组可以更简便,然而一直还没看之先mark一下吧


既然不用树状数组,那就只能用merge&sort和bst了,大神说了bst会超时,只能用avl,然后我试了试bst还真的会超时:


class Solution {public:    int sum = 0;    struct node{        node* r, *l;        int num, count;        node() :r(NULL), l(NULL), num(0), count(0){};        node(int num, int count) :r(NULL), l(NULL), num(num), count(count){};    };        void Add(node* &u, int n, int count){        if(u == NULL){            u = new node(n, count);        }        else{            if(n >= u->num){                Add(u->r, n, 0);            }else{                u->count++;                Add(u->l, n, 0);            }        }    }        void countNum(node* &u, int n, int & ans){        if(u == NULL) return;        else{            if(n > 2 * u->num){                ans += u->count + 1;                countNum(u->r, n, ans);            }else{                countNum(u->l, n, ans);            }        }            }        int reversePairs(vector<int>& nums) {        node* root = NULL;        int ans = 0;        for(auto i = nums.rbegin(); i != nums.rend(); i++){            countNum(root, *i, ans);            Add(root, *i, 0);        }        return ans;    }};


大意就是对每个倒序数先查询到底,计算出sum来,然后按照正常(小于就左子树,大于就右子树)插入(真的很麻烦,估计底下的树枝长的不得了,还不如二分暴力查找)


再就是merge&sort + 二分查找大法:


int countPairs(vector<int> &nums){    if(nums.size() <= 1) return 0;        int n = (int)nums.size();    int ans = 0;        vector<int> a(nums.begin(), nums.begin() + n/2);    vector<int> b(nums.begin() + n/2, nums.end());        ans += countPairs(a);    ans += countPairs(b);        int an = 0, bn = 0;    for(int i = 0; i<n; i++){        if(an != a.size() && (bn == b.size() || b[bn] >= a[an])){                        long temp = ceil(1.0*a[an]/2);                        int low = 0, high = (int)b.size();            while(low <= high){                int mid = (low + high) / 2;                if(b[mid] < temp) low = mid + 1;                else high = mid;                if(low == high) break;            }            ans += low;            nums[i] = a[an++];        }        else{            nums[i] = b[bn++];        }    }    return ans;}

大意就是先分再和,合的时候(求逆序对和的时候直接比较完大小就可以sum+=bn了),但是这里就不能直接sum+=,需要用二分法找到真正的bn位置,然后sum+=bn。(暴力暴力)


最后就是树状数组了

493. Reverse Pairs

不负责任粘贴他人代码

public class Solution {    public int reversePairs(int[] nums) {        int res = 0;        int n = nums.length;        if(n == 0) return res;        // reflection        Map<Long, Integer> map = new HashMap();        long[] sorted = new long[2*n];        for(int i = 0; i < n; i++) {            sorted[2*i] = nums[i];            sorted[2*i + 1] = (long) nums[i] * 2;        }        Arrays.sort(sorted);        int idx = 1;        for(long num : sorted) {            if(!map.containsKey(num)) map.put(num, idx++);        }                BIT t = new BIT(idx);        int sum = 0;        for(int j = 0; j < n; j++) {            // find how many number > 2 * nums[j]            long num = (long) nums[j];            res += sum - t.sum(map.get(num*2));            t.add(map.get(num), 1);            sum++;        }        return res;    }        class BIT {        int n;        int[] tree;        BIT(int n) { this.n = n; tree = new int[n]; }                protected int sum(int i) {            int res = 0;            while(i > 0) {                res += tree[i];                i -= i & -i;            }            return res;        }                protected void add(int i, int val) {            while(i < n) {                tree[i] += val;                i += i & -i;            }        }    }}

然后困扰了两天的题目就要继续困扰下去了。



参考:

 

Reverse Pairs (第二周:分治法)


 

【算法】逆序对问题的四种解法(归并排序,BST,树状数组,线段树)及变形