1. 程式人生 > >演算法筆試之小和問題和逆序對問題

演算法筆試之小和問題和逆序對問題

簡介

  • 小和問題
    在一個數組中,每一個數左邊比當前數小的數累加起來,叫做這個陣列的小和。
    例子:
    [1,3,4,2,5]
    1左邊比1小的數,沒有;
    3左邊比3小的數,1;
    4左邊比4小的數,1、3;
    2左邊比2小的數,1;
    5左邊比5小的數,1、3、4、2;
    所以小和為1+1+3+1+1+3+4+2=16

  • 逆序對問題
    在一個數組中,左邊的數如果比右邊的數大,則折兩個數構成一個逆序對,請列印所有逆序 對。

方法

  • 藉助歸併排序的過程,統計數量

程式碼

public class minNum {
    public static void main(String[] args){
        int[] arr={1,3,4,2,5};
        System.out.println(getMinNum(arr,0,arr.length-1));
    }

	//獲取最小和方法
    public static int getMinNum(int[] arr,int L,int R){
        if(arr==null||arr.length<=0){
            return -1;
        }
        if(L==R){
            return 0;
        }
        int mid=(L+R)/2;
        return getMinNum(arr,L,mid)+getMinNum(arr,mid+1,R)+merge(arr,L,mid,R);
    }
    
	//陣列歸併操作
    private static int merge(int[] arr, int l, int mid, int r) {
        int left=l;
        int right=mid+1;
        int[] help=new int[r-l+1];
        int index=0;
        int res=0;
        while (left<=mid&&right<=r){
            res+=arr[left]<arr[right]?(r-right+1):0;
            help[index++]=arr[left]<arr[right]?arr[left++]:arr[right++];
        }
        while(left<=mid){
            help[index++]=arr[left++];
        }
        while(right<=r){
            help[index++]=arr[right++];
        }
        for(int i=0;i<help.length;i++){
            arr[l+i]=help[i];
        }
        return res;
    }
}