劍指Offer——面試題36:數組中的逆序對

數組中的逆序對


題目:在數組中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。例如,有一個數組爲Array[0..n] 其中有元素a[i],a[j].如果 當i < j時,a[i]>a[j],那麼我們就稱(a[i],a[j])爲一個逆序對。在數組{7,5,6,4}中一共存在5對逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)。

輸入:{7,5,6,4}

輸出:5

思路:1、主要的思路就是利用歸併排序,先將數組分成每個數爲一個數組時
2、進一步,設置2個指針,P指針指向前一組的最後的一個元素,Q指針指向後一組的最後一個元素,在合併的時候判斷,前一組的最後的一個元素是否大於後一組的最後一個元素;
3、如果大於,則逆序對的數目要加上後一組中的所有元素;
4、如果小於或者等於,則將後一組的最後一個元素放在排好序的數組的最後一個元素中;另外將指針Q指針往前面移一位。
5、最後輸出逆序對的個數即可

/*
實現:數組中的逆序對
*/

#include<iostream>
#include<vector>
using namespace std;

int inverseNumber = 0;

void mergeArray(vector<int>& data, vector<int>& temp, int start, int mid, int end) {
  int tempIndex = end;
  int pIndex = mid;
  int qIndex = end;
  while (pIndex >= start && qIndex >= (mid + 1)) {
      if (data[pIndex] > data[qIndex]) {
          temp[tempIndex] = data[pIndex];
          inverseNumber += qIndex - mid;
          tempIndex--;
          pIndex--;
      }
      else {
          temp[tempIndex] = data[qIndex];
          tempIndex--;
          qIndex--;
      }
  }
  while (pIndex >= start) {
      temp[tempIndex] = data[pIndex];
      tempIndex--;
      pIndex--;
  }
  while (qIndex >= (mid + 1)) {
      temp[tempIndex] = data[qIndex];
      tempIndex--;
      qIndex--;
  }
}

void mergeSort(vector<int>& data, vector<int>& temp, int start, int end) {
    if (start < end) {
        int mid = (start + end) / 2;
        mergeSort(temp, data, start, mid);
        mergeSort(temp, data, (mid + 1), end);
        mergeArray(temp, data, start, mid, end);
    }
}

int main(){
    vector<int> number;
    int temp;
    do{
        cin >> temp;
        number.push_back(temp);
    } while (cin.get() != '\n');
    vector<int> temp;
    temp.assign(number.begin(), number.end());
    //這一塊加一個temp進去的話,就不用每次歸併的時候,都在開闢一個數組了。
    mergeSort(number, temp, 0, number.size()-1);
    for (int i = 0; i < number.size(); i++){
        cout << number[i] << " ";
    }
    cout << endl;
    cout << inverseNumber;
    system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章