왼쪽 노드의 인덱스를 기준으로 에지를 정렬 한 다음 오른쪽 노드의 인덱스를 사용하여 왼쪽 노드의 인덱스를 동일하게 정렬합니다. 오른쪽 노드의 인덱스를보십시오. 그래프의 각 교차점은이 정렬 된 목록에서 순서가 맞지 않는 한 쌍의 색인에 해당합니다. 그런 "순서가 맞지 않는"쌍을 세는 것만으로도 충분합니다.
정렬 된 목록의 오른쪽 노드의 각 색인을 순차적으로 이진 색인 트리에 삽입하십시오. 각 삽입 후에 O (log (m)) 시간에 이미 트리에있는 더 큰 인덱스가 몇 개인 지 찾을 수 있습니다. 그래서 전체 알고리즘의 시간 복잡도는 정렬을위한 O (h * log (h))와 숫자를 계산하기위한 O (h * log (m)) O (h * 인덱스 반전 수 (여기에서 'h'는 모서리 수)입니다. 기수 정렬이나 버킷 정렬을 사용하여 이것을 O (h * log (m))로 향상시킬 수 있습니다.
업데이트 : 안드로이드 디코딩 된에 의해 발견으로
, 역전 문제의 수를 병합 정렬을 기반으로하는 분할 정복 알고리즘을 사용하여 해결할 수 있습니다. 자세한 내용은 here을 참조하십시오. 이 접근법은 이진 인덱스 트리 O (h * log (m))를 사용하는 것의 복잡성보다는 시간 복잡성 O (h * log (h))가 크지 만 에지 수가 많지 않은 스파 스 그래프의 경우 메모리가 더 적고 캐시 친화적이기 때문에 더 빨라야합니다.
병합 중에 중복 항목을 제거하면 병합 정렬 방식의 복잡성이 O (h * log (m))로 향상 될 수 있습니다. 이렇게하려면 (value, numberOfInstances) 쌍에 병합 정렬을 적용합니다. 여기서 인접한 동일한 값이 적절한 'numberOfInstances'가있는 하나의 항목으로 결합됩니다. 최악의 경우, 첫 번째 로그 (m) 병합 통과에 대해 중복이 제거되지 않습니다. 이것은 O (h * log (m))의 복잡성을가집니다. 중복이 O (h) 시간에 빨리 제거되면 log (n)까지의 패스가 유지됩니다.
이진 인덱스 트리 사용 세부 정보 :
이진 인덱스 트리를 구현 가장 큰 값부터 시작하여 트리의 인덱스를 반환 할 수 있습니다 주어진 키 (가장 큰 하나 그 -> 인덱스 0, 두 번째로 큰 - > 색인 1, ...). 그런 다음 각 요소를 트리에 삽입 한 후 색인을 요청하십시오. 정렬 된 목록에서이 요소의 왼쪽에있는 큰 값의 수가됩니다.
자세한 내용 : 이진 색인 트리는 검색 트리로 구현 될 수 있으며 각 노드는 하위 노드의 카운터로 보강됩니다. 중복 요소에 대해 별도의 노드를 만들지 말고 각각에 대한 자손 노드 카운터를 업데이트하십시오.어떤 키에 대한 색인을 요구할 때, 우리는 먼저 트리에서이 색인에 해당하는 노드를 검색해야합니다. 현재 노드의 오른쪽 자손을 포함하여 현재 노드의 모든 조상의 즉각적인 오른쪽 자손에 대한 모든 카운터를 합산해야하지만, 현재 노드가 일부 조상의 오른쪽에있는 모든 경우를 제외해야합니다. 내가 제대로 우리는 우리가 NpowerM을 가질 수 있습니다 알고
우리는 (어떤 교차로가없는 설정 찾을 수 있다면 두 세트 의 관계 (이 값이 X하자) 질문을 이해 한 경우
문제 도메인에 대해 다시 생각해보십시오. 그래프 노드는 정렬되지 않으므로 위의 예제 그래프를 전혀 교차하지 않고 그릴 수 있습니다 (두 개의 열 3,1,2,4 및 1,2,4,3을 그립니다)). 따라서 노드를 그리는 방법에 대한 기하학적 제한을 두거나 최소 교차 수를 요구해야합니다 (예를 들어 수정해야합니다). – flolo