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];
}
}
}