<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 計算數組中的反轉 系列 1(使用合并排序) > 原文: [https://www.geeksforgeeks.org/counting-inversions/](https://www.geeksforgeeks.org/counting-inversions/) *數組的反轉計數*指示–數組要排序的距離(或距離)。 如果數組已經排序,則反轉計數為 0。如果數組以相反順序排序,則反轉計數為最大。 形式上講,如果 a [i] > a [j]和 i < j,則兩個元素 a [i]和 a [j]形成一個倒置 **示例**: ``` Input: arr[] = {8, 4, 2, 1} Output: 6 Explanation: Given array has six inversions: (8,4), (4,2),(8,2), (8,1), (4,1), (2,1). Input: arr[] = {3, 1, 2} Output: 2 Explanation: Given array has two inversions: (3, 1), (3, 2) ``` **方法 1(簡單)** * **方法**:遍歷數組,并為每個索引找到數組右側的較小元素的數量。 這可以使用嵌套循環來完成。 對數組中所有索引的計數求和,然后打印總和。 * **算法**: 1. 從頭到尾遍歷數組 2. 對于每個元素,使用另一個循環找到小于當前數量的元素數,直到該索引為止。 3. 總結每個索引的反轉計數。 4. 打印反轉計數。 * **實現**: ## C++ ``` // C++ program to Count Inversions // in an array #include <bits/stdc++.h> using namespace std; int getInvCount(int arr[], int n) { ????int inv_count = 0; ????for (int i = 0; i < n - 1; i++) ????????for (int j = i + 1; j < n; j++) ????????????if (arr[i] > arr[j]) ????????????????inv_count++; ????return inv_count; } // Driver Code int main() { ????int arr[] = { 1, 20, 6, 4, 5 }; ????int n = sizeof(arr) / sizeof(arr[0]); ????cout << " Number of inversions are " ?????????<< getInvCount(arr, n); ????return 0; } // This code is contributed // by Akanksha Rai ``` ## C ``` // C program to Count // Inversions in an array #include <stdio.h> int getInvCount(int arr[], int n) { ????int inv_count = 0; ????for (int i = 0; i < n - 1; i++) ????????for (int j = i + 1; j < n; j++) ????????????if (arr[i] > arr[j]) ????????????????inv_count++; ????return inv_count; } /* Driver program to test above functions */ int main() { ????int arr[] = { 1, 20, 6, 4, 5 }; ????int n = sizeof(arr) / sizeof(arr[0]); ????printf(" Number of inversions are %d \n", getInvCount(arr, n)); ????return 0; } ``` ## Java ``` // Java program to count // inversions in an array class Test { ????static int arr[] = new int[] { 1, 20, 6, 4, 5 }; ????static int getInvCount(int n) ????{ ????????int inv_count = 0; ????????for (int i = 0; i < n - 1; i++) ????????????for (int j = i + 1; j < n; j++) ????????????????if (arr[i] > arr[j]) ????????????????????inv_count++; ????????return inv_count; ????} ????// Driver method to test the above function ????public static void main(String[] args) ????{ ????????System.out.println("Number of inversions are " ???????????????????????????+ getInvCount(arr.length)); ????} } ``` ## Python3 ``` # Python3 program to count? # inversions in an array def getInvCount(arr, n): ????inv_count = 0 ????for i in range(n): ????????for j in range(i + 1, n): ????????????if (arr[i] > arr[j]): ????????????????inv_count += 1 ????return inv_count # Driver Code arr = [1, 20, 6, 4, 5] n = len(arr) print("Number of inversions are", ??????????????getInvCount(arr, n)) # This code is contributed by Smitha Dinesh Semwal ``` ## C# ``` // C# program to count inversions // in an array using System; using System.Collections.Generic; class GFG { ????static int[] arr = new int[] { 1, 20, 6, 4, 5 }; ????static int getInvCount(int n) ????{ ????????int inv_count = 0; ????????for (int i = 0; i < n - 1; i++) ????????????for (int j = i + 1; j < n; j++) ????????????????if (arr[i] > arr[j]) ????????????????????inv_count++; ????????return inv_count; ????} ????// Driver code ????public static void Main() ????{ ????????Console.WriteLine("Number of " ??????????????????????????+ "inversions are " ??????????????????????????+ getInvCount(arr.Length)); ????} } // This code is contributed by Sam007 ``` ## PHP ``` <?php? // PHP program to Count Inversions // in an array function getInvCount(&$arr, $n) { ????$inv_count = 0; ????for ($i = 0; $i < $n - 1; $i++) ????????for ($j = $i + 1; $j < $n; $j++) ????????????if ($arr[$i] > $arr[$j]) ????????????????$inv_count++; ????return $inv_count; } // Driver Code $arr = array(1, 20, 6, 4, 5 ); $n = sizeof($arr); echo "Number of inversions are ",? ???????????getInvCount($arr, $n); // This code is contributed by ita_c ?> ``` **輸出**: ``` Number of inversions are 5 ``` * **復雜度分析**: * **時間復雜度**: O(n ^ 2),需要兩個嵌套循環才能從頭到尾遍歷數組,因此時間復雜度為 O(n ^ 2) * **空間復雜度**:`O(1)`,不需要額外的空間。 **方法 2(增強合并排序)** * **Approach:** Suppose the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is – the inversions that need to be counted during the merge step. Therefore, to get a number of inversions, that needs to be added a number of inversions in the left subarray, right subarray and merge(). ![inv_count1](https://img.kancloud.cn/bd/2f/bd2fd63c3c1a3a09a6941a15a65a2cc0_559x242.png "inv_count1") **如何獲取 merge()中的反轉數?** 在合并過程中,讓我用于索引左子數組,讓 j 用于右子數組。 在 merge()的任何步驟中,如果 a [i]大于 a [j],則存在(mid – i)個反轉。 因為左子數組和右子數組已排序,所以左子數組中的所有其余元素(a [i + 1],a [i + 2]…a [mid])將大于 a [j] ![inv_count2](https://img.kancloud.cn/09/00/09005a3092fdf209f5e1c824a94c3e9e_857x413.png "inv_count2") **完整圖片**: ![inv_count3](https://img.kancloud.cn/67/f8/67f89f6d9bfc3ae91661bfc205d76214_502x472.png "inv_count3") * **算法**: 1. 這個想法類似于合并排序,將數組分成兩個相等或幾乎相等的兩半,直到達到基本情況為止。 2. 創建一個函數合并,計算合并數組的兩半時的反轉次數,創建兩個索引 i 和 j,i 是上半部分的索引,j 是下半部分的索引。 如果 a [i]大于 a [j],則存在(mid – i)個反演。 因為左子數組和右子數組已排序,所以左子數組中的所有其余元素(a [i + 1],a [i + 2]…a [mid])將大于 a [j]。 3. 創建一個遞歸函數,將數組分成兩半,然后求和前一半的求反數??,再求后一半的求反數??,然后將兩者合并,求反。 4. 遞歸的基本情況是在給定的一半中只有一個元素。 5. 打印答案 * **實現**: ## C++ ``` // C++ program to Count // Inversions in an array // using Merge Sort #include <bits/stdc++.h> using namespace std; int _mergeSort(int arr[], int temp[], int left, int right); int merge(int arr[], int temp[], int left, int mid, int right); /* This function sorts the input array and returns the? number of inversions in the array */ int mergeSort(int arr[], int array_size) { ????int temp[array_size]; ????return _mergeSort(arr, temp, 0, array_size - 1); } /* An auxiliary recursive function that sorts the input array and? returns the number of inversions in the array. */ int _mergeSort(int arr[], int temp[], int left, int right) { ????int mid, inv_count = 0; ????if (right > left) { ????????/* Divide the array into two parts and? ????????call _mergeSortAndCountInv()? ????????for each of the parts */ ????????mid = (right + left) / 2; ????????/* Inversion count will be sum of? ????????inversions in left-part, right-part? ????????and number of inversions in merging */ ????????inv_count += _mergeSort(arr, temp, left, mid); ????????inv_count += _mergeSort(arr, temp, mid + 1, right); ????????/*Merge the two parts*/ ????????inv_count += merge(arr, temp, left, mid + 1, right); ????} ????return inv_count; } /* This funt merges two sorted arrays? and returns inversion count in the arrays.*/ int merge(int arr[], int temp[], int left, ??????????int mid, int right) { ????int i, j, k; ????int inv_count = 0; ????i = left; /* i is index for left subarray*/ ????j = mid; /* j is index for right subarray*/ ????k = left; /* k is index for resultant merged subarray*/ ????while ((i <= mid - 1) && (j <= right)) { ????????if (arr[i] <= arr[j]) { ????????????temp[k++] = arr[i++]; ????????} ????????else { ????????????temp[k++] = arr[j++]; ????????????/* this is tricky -- see above? ????????????explanation/diagram for merge()*/ ????????????inv_count = inv_count + (mid - i); ????????} ????} ????/* Copy the remaining elements of left subarray? (if there are any) to temp*/ ????while (i <= mid - 1) ????????temp[k++] = arr[i++]; ????/* Copy the remaining elements of right subarray? (if there are any) to temp*/ ????while (j <= right) ????????temp[k++] = arr[j++]; ????/*Copy back the merged elements to original array*/ ????for (i = left; i <= right; i++) ????????arr[i] = temp[i]; ????return inv_count; } // Driver code int main() { ????int arr[] = { 1, 20, 6, 4, 5 }; ????int n = sizeof(arr) / sizeof(arr[0]); ????int ans = mergeSort(arr, n); ????cout << " Number of inversions are " << ans; ????return 0; } // This is code is contributed by rathbhupendra ``` ## C ``` // C program to Count // Inversions in an array // using Merge Sort #include <stdio.h> int _mergeSort(int arr[], int temp[], int left, int right); int merge(int arr[], int temp[], int left, int mid, int right); /* This function sorts the input array and returns the ???number of inversions in the array */ int mergeSort(int arr[], int array_size) { ????int* temp = (int*)malloc(sizeof(int) * array_size); ????return _mergeSort(arr, temp, 0, array_size - 1); } /* An auxiliary recursive function that sorts the input array and ??returns the number of inversions in the array. */ int _mergeSort(int arr[], int temp[], int left, int right) { ????int mid, inv_count = 0; ????if (right > left) { ????????/* Divide the array into two parts and call _mergeSortAndCountInv() ???????for each of the parts */ ????????mid = (right + left) / 2; ????????/* Inversion count will be the sum of inversions in left-part, right-part ??????and number of inversions in merging */ ????????inv_count += _mergeSort(arr, temp, left, mid); ????????inv_count += _mergeSort(arr, temp, mid + 1, right); ????????/*Merge the two parts*/ ????????inv_count += merge(arr, temp, left, mid + 1, right); ????} ????return inv_count; } /* This funt merges two sorted arrays and returns inversion count in ???the arrays.*/ int merge(int arr[], int temp[], int left, int mid, int right) { ????int i, j, k; ????int inv_count = 0; ????i = left; /* i is index for left subarray*/ ????j = mid; /* j is index for right subarray*/ ????k = left; /* k is index for resultant merged subarray*/ ????while ((i <= mid - 1) && (j <= right)) { ????????if (arr[i] <= arr[j]) { ????????????temp[k++] = arr[i++]; ????????} ????????else { ????????????temp[k++] = arr[j++]; ????????????/*this is tricky -- see above explanation/diagram for merge()*/ ????????????inv_count = inv_count + (mid - i); ????????} ????} ????/* Copy the remaining elements of left subarray ???(if there are any) to temp*/ ????while (i <= mid - 1) ????????temp[k++] = arr[i++]; ????/* Copy the remaining elements of right subarray ???(if there are any) to temp*/ ????while (j <= right) ????????temp[k++] = arr[j++]; ????/*Copy back the merged elements to original array*/ ????for (i = left; i <= right; i++) ????????arr[i] = temp[i]; ????return inv_count; } /* Driver program to test above functions */ int main(int argv, char** args) { ????int arr[] = { 1, 20, 6, 4, 5 }; ????printf(" Number of inversions are %d \n", mergeSort(arr, 5)); ????getchar(); ????return 0; } ``` ## Java ``` // Java implementation of the approach import java.util.Arrays; public class GFG { ????// Function to count the number of inversions ????// during the merge process ????private static int mergeAndCount(int[] arr, int l, int m, int r) ????{ ????????// Left subarray ????????int[] left = Arrays.copyOfRange(arr, l, m + 1); ????????// Right subarray ????????int[] right = Arrays.copyOfRange(arr, m + 1, r + 1); ????????int i = 0, j = 0, k = l, swaps = 0; ????????while (i < left.length && j < right.length) { ????????????if (left[i] <= right[j]) ????????????????arr[k++] = left[i++]; ????????????else { ????????????????arr[k++] = right[j++]; ????????????????swaps += (m + 1) - (l + i); ????????????} ????????} ????????// Fill from the rest of the left subarray ????????while (i < left.length) ????????????arr[k++] = left[i++]; ????????// Fill from the rest of the right subarray ????????while (j < right.length) ????????????arr[k++] = right[j++]; ????????return swaps; ????} ????// Merge sort function ????private static int mergeSortAndCount(int[] arr, int l, int r) ????{ ????????// Keeps track of the inversion count at a ????????// particular node of the recursion tree ????????int count = 0; ????????if (l < r) { ????????????int m = (l + r) / 2; ????????????// Total inversion count = left subarray count ????????????// + right subarray count + merge count ????????????// Left subarray count ????????????count += mergeSortAndCount(arr, l, m); ????????????// Right subarray count ????????????count += mergeSortAndCount(arr, m + 1, r); ????????????// Merge count ????????????count += mergeAndCount(arr, l, m, r); ????????} ????????return count; ????} ????// Driver code ????public static void main(String[] args) ????{ ????????int[] arr = { 1, 20, 6, 4, 5 }; ????????System.out.println(mergeSortAndCount(arr, 0, arr.length - 1)); ????} } // This code is contributed by Pradip Basak ``` ## Python3 ``` # Python 3 program to count inversions in an array # Function to Use Inversion Count def mergeSort(arr, n): ????# A temp_arr is created to store ????# sorted array in merge function ????temp_arr = [0]*n ????return _mergeSort(arr, temp_arr, 0, n-1) # This Function will use MergeSort to count inversions def _mergeSort(arr, temp_arr, left, right): ????# A variable inv_count is used to store ????# inversion counts in each recursive call ????inv_count = 0 ????# We will make a recursive call if and only if ????# we have more than one elements ????if left < right: ????????# mid is calculated to divide the array into two subarrays ????????# Floor division is must in case of python ????????mid = (left + right)//2 ????????# It will calculate inversion counts in the left subarray ????????inv_count += _mergeSort(arr, temp_arr, left, mid) ????????# It will calculate inversion counts in right subarray ????????inv_count += _mergeSort(arr, temp_arr, mid + 1, right) ????????# It will merge two subarrays in a sorted subarray ????????inv_count += merge(arr, temp_arr, left, mid, right) ????return inv_count # This function will merge two subarrays in a single sorted subarray def merge(arr, temp_arr, left, mid, right): ????i = left???? # Starting index of left subarray ????j = mid + 1 # Starting index of right subarray ????k = left???? # Starting index of to be sorted subarray ????inv_count = 0 ????# Conditions are checked to make sure that i and j don't exceed their ????# subarray limits. ????while i <= mid and j <= right: ????????# There will be no inversion if arr[i] <= arr[j] ????????if arr[i] <= arr[j]: ????????????temp_arr[k] = arr[i] ????????????k += 1 ????????????i += 1 ????????else: ????????????# Inversion will occur. ????????????temp_arr[k] = arr[j] ????????????inv_count += (mid-i + 1) ????????????k += 1 ????????????j += 1 ????# Copy the remaining elements of left subarray into temporary array ????while i <= mid: ????????temp_arr[k] = arr[i] ????????k += 1 ????????i += 1 ????# Copy the remaining elements of right subarray into temporary array ????while j <= right: ????????temp_arr[k] = arr[j] ????????k += 1 ????????j += 1 ????# Copy the sorted subarray into Original array ????for loop_var in range(left, right + 1): ????????arr[loop_var] = temp_arr[loop_var] ????return inv_count # Driver Code # Given array is arr = [1, 20, 6, 4, 5] n = len(arr) result = mergeSort(arr, n) print("Number of inversions are", result) # This code is contributed by ankush_953 ``` ## C# ``` // C# implementation of counting the // inversion using merge sort using System; public class Test { ????/* This method sorts the input array and returns the ???????number of inversions in the array */ ????static int mergeSort(int[] arr, int array_size) ????{ ????????int[] temp = new int[array_size]; ????????return _mergeSort(arr, temp, 0, array_size - 1); ????} ????/* An auxiliary recursive method that sorts the input array and ??????returns the number of inversions in the array. */ ????static int _mergeSort(int[] arr, int[] temp, int left, int right) ????{ ????????int mid, inv_count = 0; ????????if (right > left) { ????????????/* Divide the array into two parts and call _mergeSortAndCountInv() ???????????for each of the parts */ ????????????mid = (right + left) / 2; ????????????/* Inversion count will be the sum of inversions in left-part, right-part ??????????and number of inversions in merging */ ????????????inv_count += _mergeSort(arr, temp, left, mid); ????????????inv_count += _mergeSort(arr, temp, mid + 1, right); ????????????/*Merge the two parts*/ ????????????inv_count += merge(arr, temp, left, mid + 1, right); ????????} ????????return inv_count; ????} ????/* This method merges two sorted arrays and returns inversion count in ???????the arrays.*/ ????static int merge(int[] arr, int[] temp, int left, int mid, int right) ????{ ????????int i, j, k; ????????int inv_count = 0; ????????i = left; /* i is index for left subarray*/ ????????j = mid; /* j is index for right subarray*/ ????????k = left; /* k is index for resultant merged subarray*/ ????????while ((i <= mid - 1) && (j <= right)) { ????????????if (arr[i] <= arr[j]) { ????????????????temp[k++] = arr[i++]; ????????????} ????????????else { ????????????????temp[k++] = arr[j++]; ????????????????/*this is tricky -- see above explanation/diagram for merge()*/ ????????????????inv_count = inv_count + (mid - i); ????????????} ????????} ????????/* Copy the remaining elements of left subarray ???????(if there are any) to temp*/ ????????while (i <= mid - 1) ????????????temp[k++] = arr[i++]; ????????/* Copy the remaining elements of right subarray ???????(if there are any) to temp*/ ????????while (j <= right) ????????????temp[k++] = arr[j++]; ????????/*Copy back the merged elements to original array*/ ????????for (i = left; i <= right; i++) ????????????arr[i] = temp[i]; ????????return inv_count; ????} ????// Driver method to test the above function ????public static void Main() ????{ ????????int[] arr = new int[] { 1, 20, 6, 4, 5 }; ????????Console.Write("Number of inversions are " + mergeSort(arr, 5)); ????} } // This code is contributed by Rajput-Ji ``` **輸出**: ``` Number of inversions are 5 ``` * **復雜度分析**: * **時間復雜度**:`O(N log N)`,使用的算法是分治法,因此在每個級別中需要一個完整的數組遍歷,并且存在 log n 個級別,因此時間復雜度為`O(N log N)`)。 * **空間復雜度**:`O(n)`,臨時數組。 注意上面的代碼修改(或排序)輸入數組。 如果我們只想計算倒數,那么我們需要創建一個原始數組的副本,并在副本上調用 mergeSort()。 您可能想看看。 [計數數組中的求反| 集合 2(使用自平衡 BST)](https://www.geeksforgeeks.org/count-inversions-in-an-array-set-2-using-self-balancing-bst/) [使用 C++ STL 中的 Set 計數反轉](http://quiz.geeksforgeeks.org/counting-inversions-using-set-in-c-stl/) [計數數組中的反轉| 第 3 組(使用 BIT)](https://www.geeksforgeeks.org/count-inversions-array-set-3-using-bit/) **參考**: [http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf](http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf) [http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm](http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm) 如果您在上述程序/算法或其他解決相同問題的方法中發現任何錯誤,請發表評論。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看