算法笔记-归并算法面试题、逆序数问题

本文介绍了一种利用归并排序算法解决逆序对问题的方法,并提供了详细的实现步骤与代码示例。逆序对是指在一个数组中,若左侧的数大于右侧的数,则这对数称为逆序对。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 题目

逆序对问题:在一个数组中,左边的数如果比右边大,则这两个数构成一个逆序对,请打印所有逆序对

比如说:
数组: 5, 1, 3,4,2

第一个元素是5,其右边有小于5的数,即1,3,4,2,所以其逆序对是5,1; 5,3; 5,4; 5,2共计四对
第二个元素是1,其右边没有比该元素小的数,所以没有逆序对
第三个元素是3,其右边的2是小于该元素的数,所以其逆序对是3,2
第四个元素是4,其右边的2是小于该元素的数,所以其逆序对是4,2
第五个元素是2,其右边没有元素,没有逆序数

2. 思路

这个和前面一片文章是同一思路,点击此处,都是通过归并算法来考虑,不同的是,此处我们需要按从大到小来排序,只要左边数组某元素大于右边数组某元素,那么一定大于包括右边该元素以内所有的数

3. 程序

class Program
    {
        static void Main(string[] args)
        {
            int[] t1 = { 5, 1, 3,4,2};
            InversionPair.StartRecursion(t1, 0, t1.Length - 1);
            Console.Read();
        }
    }

class Problem2
    {
        //逆序对问题:在一个数组中,左边的数如果比右边大,则这两个数构成一个逆序对,请打印所有逆序对
    }

    public class InversionPair
    {
        public static void StartRecursion(int[] arr,int L,int R)
        {
            if (L==R)
            {
                return;
            }
            int M = L + ((R - L) >> 1);//中点位置
            StartRecursion(arr, L, M);
            StartRecursion(arr, M + 1, R);
            MergeRecursion(arr, L, R, M);
        }

        public static void MergeRecursion(int[] arr,int L,int R,int M)
        {
            //从大到小排序
            int[] replace = new int[R - L + 1];
            int i = 0;
            int p1 = L;
            int p2 = M + 1;
            while (p1<=M&&p2<=R)
            {
            //打印逆序对
                if (arr[p1] > arr[p2] )
                {
                    var t1 = arr[p1];
                    //大于右边数组某个数,那么arr[p1]肯定也大于右边数组里的该数以后的数,均为逆序对
                    for (int z = 0; z < R-p2+1; z++)
                    {
                        var t2 = arr[p2+z];
                        Console.WriteLine($"逆序对:{t1},{t2}");
                    }
                    
                }
               replace[i++] = arr[p1] > arr[p2] ? arr[p1++] : arr[p2++];
            }
            while (p1<=M)
            {
                replace[i++] = arr[p1++];
            }
            while (p2 <= R)
            {
                replace[i++] = arr[p2++];
            }
            for (int j = 0; j < replace.Length; j++)
            {
                arr[L + j] = replace[j];
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值