zoukankan      html  css  js  c++  java
  • 刷题笔记-排序

    归并排序 -模板题

    思路:

    1.确定分界点 mid = l + r >> 2
    2.递归排序Left、Right部分
    3.使用双指针算法归并排序Left、Right部分

    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int N = 100010;
    int a[N],tmp[N];
    
    void merge_sort(int *a , int l, int r)
    {
        //如果子序列小于等于1,则返回
        if(l >= r)  return;
        int mid = l + r >> 1;
        //递归排序
        merge_sort(a, l, mid),  merge_sort(a, mid+1 , r);
        //归并合二为一
        int i = l, j = mid + 1, k = 0;
        while(i <= mid && j <= r)
            if(a[i] <= a[j])   tmp[k++] = a[i++];
            else tmp[k++] = a[j++];
        while(i <= mid)   tmp[k++] = a[i++];
        while(j <= r)     tmp[k++] = a[j++];
        //在放回原数组
        for(i = l, j = 0; i <= r; i++, j++)
            a[i] = tmp[j];
    }
    
    int main(void)
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)    cin >> a[i];
       
        merge_sort(a,0,n-1);
        
        for(int i = 0; i < n; i++)   cout << a[i] << ' ';
        
        return 0;
    }
    

    逆序对的数量

    思路:

    1.总的数量等于 Left边中逆序对的数量、Right边中逆序对的数量、Left、Right两边的元素共同组成的逆序对的数量
    2.如何求算Left、Right两边的元素共同组成的逆序对的数量?

    • 考虑Right中元素被放入tmp数组中,即表示此元素小于Left边中任意元素,所以有 ans += mid - i + 1;

    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    typedef long long int LL;
    
    const int N = 100010;
    int a[N],tmp[N];
    
    LL merge_sort(int *a , int l, int r)
    {
        //如果子序列小于等于1,则返回
        if(l >= r)  return 0;
        int mid = l + r >> 1;
        //递归排序
        LL res = merge_sort(a, l, mid) + merge_sort(a, mid+1 , r);
        //归并合二为一
        int i = l, j = mid + 1, k = 0;
        while(i <= mid && j <= r)
            if(a[i] <= a[j])   
            {
                tmp[k++] = a[i++];
            }
            else 
            {   
                res += (LL)mid - i + 1;
                tmp[k++] = a[j++];
            }
            
        while(i <= mid)   tmp[k++] = a[i++];
        while(j <= r)     tmp[k++] = a[j++];
        //在放回原数组
        for(i = l, j = 0; i <= r; i++, j++)
            a[i] = tmp[j];
        
        return res;
    }
    
    int main(void)
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)    cin >> a[i];
       
        LL ans = merge_sort(a,0,n-1);
        
        cout << ans << endl;
        
        return 0;
    }
    
  • 相关阅读:
    腾讯2017校招编程:一个数等于两个素数的和
    人类简史:从动物到上帝
    讨论:研发团队到底应该是制定OKR还是制定KPI?
    绩效主义毁了索尼
    研发团队是该制定OKR还是KPI?
    一切不行,都是“人”的不行?
    能力陷阱:能力越强,越容易失败
    一个好的产品经理到底有多么重要?
    管理:不会把目标翻译成任务,要你何用?
    做一个有产品思维的研发:Scrapy安装
  • 原文地址:https://www.cnblogs.com/zy200128/p/12673543.html
Copyright © 2011-2022 走看看