題目:
在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。例如在陣列中一共存在5對逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)基本思想:解法一:o(n^2)
最簡單的想法就是遍歷每乙個元素,讓其與後面的元素對比,如果大於則count++,但是這樣的時間複雜度是o(n^2)。
解法二:o(nlogn)
歸併排序思路:
例如7,5,4,6可以劃分為兩段7,5和4,6兩個子陣列
1.在7,5中求出逆序對,因為7大於5所以有1對
2.在6,4中求出逆序對,因為6大於4所以逆序對再加1,為2
3.對7,5和6,4進行排序,結果為5,7,和4,6
4.設定兩個指標分別指向兩個子陣列中的最大值,p1指向7,p2指向6
5.比較p1和p2指向的值,如果大於p2,因為p2指向的是最大值,所以第二個子陣列中有幾個元素就有幾對逆序對(當前有兩個元素,逆序對加2,2+2=4),7>6,比較完之後將p1指向的值放入輔助陣列裡,輔助陣列裡現在有乙個數字7,然後將p1向前移動一位指向5
6.再次判斷p1和p2指向的值,p1小於p2,因為p1指向的是第乙個子陣列中最大值,所以子陣列中沒有能和當前p2指向的6構成逆序對的數,將p2指向的值放入輔助陣列,並向前移動一位指向4,此時輔助陣列內為6,7
7.繼續判斷p1(指向5)和p2(指向4),5>4,第二個子陣列中只有乙個數字,逆序對加1,4+1=5,為5對,然後將5放入輔助陣列,第乙個子陣列遍歷完畢,只剩下第二個子陣列,當前只有乙個4,將4也放入輔助陣列,函式結束。輔助陣列此時為4,5,6,7.逆序對為5.
#include using namespace std;
int inversepairscore(int* data,int* copy,int start,int end)
int length =(end - start)/2;
int left=inversepairscore(copy,data,start,start+length);
int right=inversepairscore(copy,data,start+length+1,end);
int i=start+length; //i初始化為前半段最後乙個數字的下標
int j=end; //j初始化為後半段最後乙個數字的下標
int indexcopy=end;
int count=0;
while(i>=start && j>= start+length+1)
else
} for(;i>=start;--i)
copy[indexcopy--]=data[i];
for(;j>=start+length+1;--j)
copy[indexcopy--]=data[j];
return left+right+count;
} int inversepairs(int* data,int length)
{ if(data == null || length <0)
return 0;
int* copy=new int[length];
for(int i =0;i
時間複雜度為o(nlogn),但是要乙個長度為n的輔助陣列,所以空間複雜度為o(n)
。
劍指offer 面試題36 陣列中的逆序對
題目 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。思路 歸併排序的合併過程。主要是考慮合併兩個有序序列時,計算逆序對數。對於兩個公升序序列,設定兩個下標 兩個有序序列的末尾。每次比較兩個末尾值,如果前末尾大於後末尾值,則...
劍指Offer之面試題36 陣列中的逆序對
所有 均通過g 編譯器 測試,僅為練手紀錄。面試題36 陣列中的逆序對 題目 在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。面試題36 陣列中的逆序對 題目 在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成...
《劍指offer》陣列相關面試題
在乙個長度為n的陣列裡所有數字都在0 n 1範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複,也不知道重複了幾次,請找出陣列中任意乙個重複的數字。例如,長度為7的陣列,那麼對應的輸出應該是重複的數字2或者3.思路 重排這個陣列,從頭到尾依次掃瞄這個陣列中的每個數字。掃到下標為i的數字m時 首先...