陣列中的逆序對

2021-10-10 20:37:46 字數 2881 閱讀 2927

2.1  思路分析

使用雙重迴圈,外迴圈遍歷陣列每個元素,內迴圈遍歷外迴圈當前元素之後的元素,符合條件的進行計數; 

2.2  **實現

class solution 

}return count;

}}

2.3  複雜度分析

3.1  思路分析

看到要求方案總數,故想到動態規劃,定義狀態dp[i]表示以nums[i]為結尾的逆序總數;

初始化狀態dp[0] = 0;

關於狀態轉移方程,需要dp[i-1]加上[nums[0],nums[i-1]]中大於nums[i]的個數,假設用count表示,那麼dp[i] = dp[i-1] + count;

該方法同暴力法一樣,具有較高的時間複雜度,在測試中超時。

3.2  **實現

class solution 

return dp[nums.length-1];

}//返回count

public int reversecount(int nums,int i)

return res;

}}

3.3  複雜度分析

4.1  思路分析

假設現在陣列劃分成的左(leftarr)、右(rightarr)陣列均有序,通過leetcode官方題解可知,若遍歷右陣列中的元素(索引j)小於遍歷左陣列的元素(索引i)時,那麼從索引i~ 索引j構成的逆序個數就是左陣列中剩餘的元素( i 之前的元素被合併到乙個新的陣列中);

我們首先在之前寫的歸併排序**的基礎上實現,然後在利用官方的形式實現一遍,雖然形式不同,但原理相同;

4.2  **實現1

class solution 

for (int j = mid + 1; j <= right; j++)

// 新建三指標

int i = 0;

int j = 0;

int k = left;

int count = 0;

// 開始合併有序陣列

while (i < leftsize && j < rightsize) else

} while (i < leftsize)

while (j < rightsize)

return count;

} /**

* 該方法用來實現對無序陣列的排序

* 假定左子陣列區間[left,mid],右子陣列區間[mid+1,right]

* @param arr

* @param left

* @param right

*/public static int mergesort(int arr,int left,int right)

public static void main(string args) ;

//int arr = ;

int count = mergesort(arr,0,7);

system.out.println(count);

}}

4.3  **實現2

class solution 

//拷貝原陣列

int copy = new int[nums.length];

for(int i = 0; i < copy.length; i++)

//用於歸併排序

int temp = new int[nums.length];

return mergesortpairs(copy,0,copy.length-1,temp);//[left,right]

}/**

* 該方法用來返回逆序總數

*/public int mergesortpairs(int copy,int left,int right,int temp)

int mid = left + (right - left)/2;

int leftpairs = mergesortpairs(copy,left,mid,temp);

int rightpairs = mergesortpairs(copy,mid+1,right,temp);

//若當前已經是個有序陣列了,就直接返回

if(copy[mid] <= copy[mid+1])

int crosspairs = mergesortcount(copy,left,right,temp);

return leftpairs + rightpairs + crosspairs;

}/**

* 該方法返回當前陣列對應的逆序數

*/public int mergesortcount(int copy,int left,int right,int temp)

int mid = left + (right - left)/2;

int i = left;

int j = mid + 1;

int count = 0;

for(int k = left; k <= right; k++) else if(j == right + 1) else if(temp[i] <= temp[j]) else

}return count;

}}

陣列中逆序對

題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...

陣列中的逆序對

來自劍指offer 分析 我們第一反應是順序掃瞄整個陣列,每掃瞄到乙個數字時,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這個兩個數字就組成了乙個逆序對。假設陣列有n個數字,由於每個數字都要和o n 個數字作比較,因此這個演算法的時間複雜度為o n 2 換思路 我們採用歸併思想,先考...

陣列中的逆序對

題目 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。用歸併排序演算法,歸併的時候,從後向前歸併。include using namespace std int getreversenum int p1,int p2,int...