Google interview question: mergeSort-like questions

排序有关的问题在面试题中相当多。对于参加面试的人来说,最基本的merge sort和quick sort肯定是必须掌握的,而且要能快速地写出bug free的代码。这次总结的是两道mergeSort-like问题。

Question 1: 

qaz is a value for a number where this number is less than the other next values which have indexes larger than the index of this number.
for example: 33 , 25 , 26 , 58 , 41 , 59 -> qaz of (33) = 3 where 33 less than 3 numbers (58 , 41 , 59), qaz of (25) = 4 and not 5 because the index of 33 is less than the index of 25, qaz of (26) = 3 , qaz of (58) = 1 , qaz of (41) = 1 , qaz of (59) = 0.

 

Naive的算法就是brute force,检测每一对元素的大小关系,时间复杂度为O(N^2)。仔细一看就能发现题目的本质就是排序的算法。如果你用tree sort的思路来建立平衡二叉树,自然也可以解决这个问题(建立一颗空树,依次插入元素,节点存储比它大的元素的个数,时间复杂度为O(Nlog(N)),空间复杂度为O(N))。但这对于面试题来说显然是自找麻烦。很容易想到的方法即merge sort(时间复杂度为O(Nlog(N)),空间复杂度为O(N)),而merge sort中改变元素位置的操作是merge操作。因此,在merge操作中A数组(左边)和B数组(右边)合并时,若选择的元素a在A数组,则qaz(a)+=B剩余的元素数量,因为这些数原本出现在a右边并大于a;若选择的元素a在B数组,则不需要更新qaz(a)的值。

public class mergeSort1 {
    public static void main(String arcg[]){
        mergeSort1 h = new mergeSort1();
        int[] array = {33,25,26,58,41,59};
        pair[] array2 = new pair[array.length];
        for(int i=0;i<array.length;i++){
            array2[i] = h.new pair(array[i]);
        }
        h.sort(array2);
        for(int i=0;i<array2.length;i++){
            System.out.println(array2[i].val + ": " + array2[i].qaz);
        }
    }
    class pair{
        int val;
        int qaz;
        public pair(int val){
            this.val = val;
            qaz = 0;
        }
    }
    private pair[] array;
    private pair[] helper;
    void sort(pair[] array){
        this.array = array;
        this.helper = new pair[array.length];
        mergeSort(0,array.length-1);
    }
    void mergeSort(int low, int high){
        if(low < high){
            int mid = low+(high-low)/2;
            mergeSort(low, mid);
            mergeSort(mid+1, high);
            merge(low,mid,high);
        }
    }
    void merge(int low, int mid, int high){
        for(int i=low;i<=high;i++) helper[i] = array[i];
        int i=low, j=mid+1,k=low;
        while(i<=mid && j<=high){
            if(helper[i].val<=helper[j].val){
                array[k] = helper[i++];
                array[k].qaz += high-j+1;
            }
            else{
                array[k] = helper[j++];
            }
            k++;
        }
        while(i<=mid) array[k++] = helper[i++];
    }
}

 

Question 2:

Counting inversion. 

Finding "similarity" between two rankings. Given a sequence of n numbers 1..n (assume all numbers are distinct). Define a measure that tells us how far this list is from being in ascending order. The value should be 0 if a_1 < a_2 < ... < a_n and
should be higher as the list is more "out of order".

Example

2 4 1 3 5
1 2 3 4 5

The sequence 2, 4, 1, 3, 5 has three inversions (2,1), (4,1), (4,3).

 

和第一题同样的思路,在merge操作时当选择的元素在B数组中的时候,会产生A数组剩余元素数量的逆序。

public class mergeSort2 {
    public static void main(String arcg[]){
        int[] input = {2,4,1,3,5};
        sort(input);
        System.out.println(invertionCount);
    }
    private static int[] array;
    private static int[] helper;
    private static int invertionCount;
    public static void sort(int[] input){
        array = input;
        helper = new int[array.length];
        mergeSort(0,array.length-1);
    }
    public static void mergeSort(int low, int high){
        if(low<high){
            int mid = low+(high-low)/2;
            mergeSort(low,mid);
            mergeSort(mid+1,high);
            merge(low,mid,high);
        }        
    }
    public static void merge(int low, int mid, int high){
        for(int i=low;i<=high;i++)
            helper[i] = array[i];
        int i=low,j=mid+1,k=low;
        while(i<=mid && j<=high){
            if(helper[i] < helper[j]){
                array[k++] = helper[i++];
            }
            else{
                invertionCount+=mid-i+1;
                array[k++] = helper[j++];
            }
        }
        while(i<=mid) array[k++] = helper[i++];
    }
}

 

posted @ 2015-06-28 02:18  dshao  阅读(222)  评论(0编辑  收藏  举报