LeetCode315—Count of Smaller Numbers After Self—Java版归并算法

来源:互联网 发布:java合并list 编辑:程序博客网 时间:2024/05/18 09:02

这是我在研究leetcode的solution第一个解决算法时,自己做出的理解,并且为了大家能看懂,做出了详细的注释。

此算法算是剑指Offer36的升级版,都使用的归并算法,但是此处的算法,难度更高,理解起来更加费劲。

/* * @Param res 保存逆变对数 * @Param index 保存数组下标索引值,排序数组下标值。 * 此算法使用归并算法,最大差异就在于merge()方法的转变 *  *  */  public List<Integer> countSmaller(int[] nums) {        int[] res = new int[nums.length];        int[] index = new int[res.length];        for (int i = 0; i < res.length; i++) {            index[i] = i;        }        mergeSort(nums, index, 0, nums.length-1, res);        List<Integer> list = new LinkedList<>();        for (int i : res) {            list.add(i);        }        return list;    }        private void mergeSort(int[] nums, int[] index, int l, int r, int[] res) {        if (l >= r) {            return;        }        int mid = (l+r)/2;        mergeSort(nums, index, l, mid, res);        mergeSort(nums, index, mid+1, r, res);        merge(nums, index, l, mid, mid+1, r, res);    }    /* * 将左右两边排序好的数组进行逆序对计算,分别从左边起始处和右边起始处开始比较, * 当,左边索引值大于右边时,count++,否则 左边索引值++; * count值会一直保留,如果右边数组遍历到尾部,左边数组剩下的数的逆序数都会是count; *  *  *  */private void merge(int[] nums, int[] index, int l1, int r1, int l2, int r2, int[] res) {int start = l1;    int[] tmp = new int[r2-l1+1];    //记录逆序对数    int count = 0;    //temp数组的下标值    int p = 0;    while (l1 <= r1 || l2 <= r2) {    //左边数组遍历结束后,将右边剩余的值放到temp数组中,        if (l1 > r1) {            tmp[p++] = index[l2++];         //右边数组遍历结束后,将左边剩余的值放到temp数组中,        } else if (l2 > r2) {        //l1是原数组索引值,index[l1]是排序好的原数组中索引值。res[index[l1]]对应的原数组索引位置赋逆变数            res[index[l1]] += count;            tmp[p++] = index[l1++];        } else if (nums[index[l1]] > nums[index[l2]]) {            tmp[p++] = index[l2++];            count++;        } else {        //res存放每个数的最大值            res[index[l1]] += count;            tmp[p++] = index[l1++];        }    }    for (int i = 0; i < tmp.length; i++) {    //根据数组值排序,将对应的索引值放到index数组中。        index[start+i] = tmp[i];    }}


原创粉丝点击