Ordem inversa vs. método de classificação de mesclagem para dividir e conquistar

Introdução ao par reverso

Se houver um número inteiro positivo i, j tal que 1 ≤ i <j ≤ n e A [i]> A [j], então o par ordenado de <A [iGirl, A [jorgeous> é chamado par inverso de A, e Chamado o número da ordem inversa.

Resolva o número de pares reversos em uma matriz

De fato, é encontrar um grande número com um pequeno índice, então não vamos falar primeiro sobre violência, a violência é obviamente O (n 2 ), 8 Taihang

int unseq(vector<int> &nums)
{
	int cnt = 0;
	for(int i=0; i<nums.size(); i++)
		for(int j=i+1; j<nums.size(); j++)
			if(nums[i]>nums[j]) cnt++;
	return cnt;
}

Divida e conquiste o pensamento: classifique por fusão

Para o número de pares na ordem inversa na matriz, divida a matriz em intervalos [l, mid]AND [mid+1, r], e o problema pode ser decomposto em subproblemas:

  • Subarray [l, mid]inverter o número lcnt
  • [mid+1, r]Número do par de ordem inversa do subconjunto rcnt
  • A [i] está à esquerda, A [j] está à direita e o par de <i, j> de A [i]> A [j]

As perguntas 1 e 2 podem ser resolvidas recursivamente, então a chave é como encontrar a pergunta 3, ou seja,

Observe que, ao resolver o problema 12 aqui, não apenas a solução, mas também a matriz é classificada, ou seja, os lados esquerdo / direito estão em um estado ordenado , então podemos usar o tempo O (n) para concluir a solução

  • Na sub-matriz direita, enumere j subscritos de trás para frente
  • Na sub-matriz esquerda, defina o ponteiro i, no início i aponta para o meio
  • i Deslize para a esquerda para encontrar o primeiro i tal que A [i] <= A [j]
  • Anterior descrição i+1 ~ midsubscrito, a [i] é maior do que A [j]
  • Em seguida, para A [j] a reverter para a direita, encontrado mid-iem

Como os dois lados são ordenados, então para o j subscrito, porque A [j] está diminuindo, então A[j+1]配对的个数,同样可以运用到A[j], além disso, devemos julgar adicionalmente se A [j] pode encontrar mais pares de ordem reversa

Aqui , a ordem dos dois lados da matriz é usada e os resultados anteriores são usados ​​disfarçados para economizar tempo

Parece ser um loop duplo; de fato, i, j não volta mais de n / 2 vezes, portanto a complexidade é O (n)

Usando o tempo O (n) para encontrar o número de pares na ordem inversa, também precisamos mesclar a matriz para facilitar a recursão anterior para continuar a pesquisa

Use [ função inplace_merge ] para operação de mesclagem

Você pode ter muitos pontos de interrogação aqui:

Após a classificação, o pedido não é interrompido?

Antes de embaralhar a ordem (classificação), obtivemos o número de soluções dos sub-arranjos em ambos os lados
e , ao resolver o par reverso da cruz , a esquerda e a direita são classificadas, mas suas posições relativas permanecem inalteradas , ou seja, o elemento esquerdo Subarray à esquerda, o mesmo à direita

int unseq(vector<int> &nums, int l, int r)
{
	if(l>=r || l<0 || r>=nums.size()) return 0;
	int mid=(l+r)/2, cnt=0, i=mid;
	int lcnt = unseq(nums, l, mid);
	int rcnt = unseq(nums, mid+1, r); 
	for(int j=r; j>mid; j--)
	{
		while(i>=l && nums[j]<nums[i]) i--;
		cnt += mid-i;
	}
	inplace_merge(nums.begin()+l, nums.begin()+mid+1, nums.begin()+r+1);
	return lcnt+rcnt+cnt;
}

Código completo

#include <bits/stdc++.h>

using namespace std;

int unseq(vector<int> &nums, int l, int r)
{
	if(l>=r || l<0 || r>=nums.size()) return 0;
	int mid=(l+r)/2, cnt=0, i=mid;
	int lcnt = unseq(nums, l, mid);
	int rcnt = unseq(nums, mid+1, r); 
	for(int j=r; j>mid; j--)
	{
		while(i>=l && nums[j]<nums[i]) i--;
		cnt += mid-i;
	}
	inplace_merge(nums.begin()+l, nums.begin()+mid+1, nums.begin()+r+1);
	return lcnt+rcnt+cnt;
}

int unseq(vector<int> &nums)
{
	int cnt = 0;
	for(int i=0; i<nums.size(); i++)
		for(int j=i+1; j<nums.size(); j++)
			if(nums[i]>nums[j]) cnt++;
	return cnt;
}

int main()
{	
	vector<int> nums{2,7,4,3,1,8,6,5};
	cout<<unseq(nums)<<endl;
	cout<<unseq(nums, 0, nums.size()-1)<<endl;
	for(int i=0; i<nums.size(); i++) cout<<nums[i]<<" ";
	cout<<endl;
	
	return 0;
}
Publicado 262 artigos originais · ganhou 11 · 10 mil visualizações

Acho que você gosta

Origin blog.csdn.net/weixin_44176696/article/details/105092613
Recomendado
Clasificación