배열 의 역순 대 수량, 시간 복잡 도 O (n * lg n) 를 구하 십시오.
2974 단어 데이터 구조 와 알고리즘
알고리즘 서론 제3 판 2 장의 네 번 째 사고 문제 다.
원제:
A [1... n] 가 n 개의 다른 수 를 가 진 배열 이 라 고 가정 합 니 다.만약 에 i < j 및 A [i] > A [j] 라면 대구 (i, j) 를 A 의 역순 대 라 고 부른다.
n 개 요소 의 모든 배열 에서 역순 으로 수량 을 확인 하 는 알고리즘 을 제시 합 니 다. 시간 복잡 도 O (n * lg n).
(알림: 병합 정렬 수정)
분석 하 다.
먼저 직관 적 인 해법 이 있다. 즉, 배열 A 를 차례대로 옮 겨 다 니 며 요소 A [i] 뒤에 몇 개의 작은 숫자 가 존재 하 는 지 찾 아 총 횟수 를 통계 하면 된다.그러나 이런 해법 은 간단 하지만 시간 복잡 도 는 O (n ^ 2) 이 고 코드 도 간단 합 니 다. 여 기 는 예 를 들 지 않 습 니 다.다음은 병합 정렬 방법 으로 역순 의 수량 을 계산 하 는 방법 을 말한다.
병합 단계 에 역순 이 얼마나 존재 하 는 지 항상 역순 대 수량 = 왼쪽 부분 역순 대 + 오른쪽 부분 역순 대 + 합병 부분 역순 대 가 있 습 니 다.
관건 은 합병 부분의 역순 대 수량 을 어떻게 얻 느 냐 하 는 것 이다. 합병 할 때 i 가 왼쪽 배열 의 역순 색인 이 고 j 는 오른쪽 배열 의 역순 색인 이다. A [i] 가 A [j] 보다 크다 는 것 을 발견 하면 (mid – i) 의 역순 이 생 길 것 이다.A [i + 1], A [i + 2]... A [mid - 1] 가 A [j] 보다 크기 때문이다.그 중 mid 는 오른쪽 배열 에서 시 작 된 색인 입 니 다.
해답
public class Main {
public static void main(String[] args) {
int[] arr = new int[] { 2, 3, 8, 6, 1 };
int inversionCount = mergeSort(arr, 0, arr.length);
printArray(arr);
System.out.println("inversionCount: " + inversionCount);
}
public static int mergeSort(int[] arr, int start, int end) {
int inversionCount = 0;
int length = end - start;
if (length > 1) { // 1
int mid = (start + end) / 2;
inversionCount += mergeSort(arr, start, mid); // sort left
inversionCount += mergeSort(arr, mid, end); // sort right
inversionCount += merge(arr, start, mid, end);
}
return inversionCount;
}
public static int merge(int[] arr, int start, int mid, int end) {
// check input
if (arr == null || start < 0 || end > arr.length) {
return 0;
}
int[] temp = new int[end - start];
int inversionCount = 0;
int i = start; //
int j = mid; //
int k = 0; // temp
while (i < mid && j < end) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
// arr[i] > arr[j], (mid - i)
inversionCount += mid - i;
}
}
if (i != mid) {
System.arraycopy(arr, i, temp, k, mid - i);
}
if (j != end){
System.arraycopy(arr, j, temp, k, end - j);
}
System.arraycopy(temp, 0, arr, start, temp.length);
return inversionCount;
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
실행 결과:
1 2 3 6 8
inversionCount: 5
원수 조 는 [2, 3, 8, 6, 1] 이 고 그 역순 대 는 (2, 1), (3, 1)、 (8, 1)、 (6, 1)、 (8, 6) 모두 5 쌍 입 니 다.
우리 운행 결과 에 부합 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[JAVA] 배열 회전 출력요소 가 출력 을 시작 하 는 위치 에 주의 하 십시오. 모두 몇 라운드 의 수출 이 있 습 니까? n/2 + 1 매 라 운 드 는 상, 우, 하, 좌 로 나 뉜 다. 각 방향의 시작 위치 와 좌표 의 관 계 를 구...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.