數組中的逆序對

 有一組數,對於其中任意兩個數組,若前面一個大於後面一個數字,則這兩個數字組成一個逆序對。請設計一個高效的算法,計算給定數組中的逆序對個數。

 給定一個int數組A和它的大小n,請返回A中的逆序對個數。保證n小於等於5000。

測試樣例:

輸入:[1,2,3,4,5,6,7,0],8

返回:7

 這道題如果用常規的遍歷數組,對每個元素再進行數組的遍歷,時間複雜度爲O(n),肯定會超時,下面介紹一種時間複雜度爲O(nlogn)。


/**
 * 封裝的一個數據類
 */
class Node {

    // 值
    int value;
    // 比當前節點value大的節點數
    int leftSize = 0;
    Node left, right;


    public Node(int value) {
        this.value = value;
    }

    /**
     * 將比自己大的節點放到前面,leftSize++,比自己小的,放到自己後面
     */
    public void insert(int val) {

        if (val > this.value) {
            if (left != null) {
                left.insert(val);
            } else {
                left = new Node(val);
            }
            leftSize++;
        } else {
            if (right != null) {
                // 調用後面的節點的排序,隨時保持leftSize的更新
                right.insert(val);
            } else {
                right = new Node(val);
            }
        }
    }

    // 得到比自己大的節點的數量
    public int getRank(int val) {
        if (val == this.value) {
            return leftSize;
        } else if (val > this.value) {
            return left.getRank(val);
        } else {
            return leftSize + 1 + right.getRank(val);
        }
    }


}

public class AntiOrder {

    Node root = null;

    public int count(int[] A, int n) {
        int res = 0;
        for (int i = 0; i < n; i++) {
            res += helper(A[i]);
        }
        return res;
    }

    public int helper(int n) {
        if (this.root == null) {
            root = new Node(n);
            return 0;
        } else {
            root.insert(n);
            return root.getRank(n);
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章