算法训练|交易逆序对的总数、验证二叉搜索树的后序遍历

LCR 170. 交易逆序对的总数 - 力扣(LeetCode)

总结:这道题目难度比较大,整体上来说是利用归并排序的思想,在[并]的过程中加入操作得到目标数,题解部分解析:要注意的地方在于是当左边指针移动的时候我们就需要计算一次交易逆序对,不是右指针移动的时候计算是因为,当我们移动右指针时,说明左边的数比右边的大,右指针移动完成后其中间所跨过的数就是逆序对。即:左指针指向的数比这其中跨过的数都要大,而这些数按照排序本应在左边而此时在右边,所以构成了一对逆序对。最后在将剩余的数添入数组时也需要在左指针移动时计算一次逆序对数。以及不要忘记在最后的过程中将排序好的数组复制替代掉原来的数组。

代码:

class Solution {
public:
    int mergeSort(vector& record,vector& tmp,int l,int r)
    {
        if(l >= r)
        return 0;

        int mid = (l + r) / 2;
        int inv_count = mergeSort(record,tmp,l,mid) + mergeSort(record,tmp,mid + 1,r);

        int i = l,j = mid + 1,pos = l;
        while(i <= mid && j <= r)
        {
            if(record[i] <= record[j])
            {
                tmp[pos++] = record[i++];
                inv_count += j - mid - 1;
            }
            else
            {
                tmp[pos++] = record[j++];
            }
        }
        while(i <= mid)
        {
            tmp[pos++] = record[i++];
            inv_count += j - mid - 1;
        }
        while(j <= r)
        tmp[pos++] = record[j++];
        copy(tmp.begin() + l,tmp.begin() + r + 1,record.begin() + l);
        return inv_count;
    }
    int reversePairs(vector& record) {
        int n = record.size();
        vector tmp(n);
        return mergeSort(record,tmp,0,n - 1);
    }
};

LCR 152. 验证二叉搜索树的后序遍历序列 - 力扣(LeetCode)

总结:此题是利用递归方法来解决问题,容器中最后一个数即为根节点,进行循环寻找到第一个比根节点大的数从此数记为FirstMax开始即为右孩子树,而根据二叉搜索树的性质,在容器中在FirstMax之前的数即为左孩子树。则在容器中FirstMax之前的数都应比根节点要小,之后的数都应比根节点要大,利用此点进行递归比较。

代码:

class Solution {
public:
    bool recur(vector& postorder,int i,int j)
    {
        if(i >= j)
        return true;
        int p = i;
        while(postorder[p] < postorder[j]) p++;
        int m = p;
        while(postorder[p] > postorder[j]) p++;

        return p == j && recur(postorder,i,m - 1) && recur(postorder,m,j - 1);
    }
    bool verifyTreeOrder(vector& postorder) {
        return recur(postorder,0,postorder.size() - 1);
    }
};

你可能感兴趣的:(算法,排序算法)