题解 | #数组中的逆序对#

数组中的逆序对

http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

    //统计逆序对的个数
    int ret = 0;

    public int InversePairs(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }
        //使用归并排序的方式统计
        divide(array, 0, array.length - 1);
        return ret;
    }

    private void divide(int[] array, int start, int end) {
        //递归的终止条件
        if (start >= end) {
            return;
        }
        //计算中间值,注意溢出
        int mid = start + (end - start) / 2;
        //递归分
        divide(array, start, mid);
        divide(array, mid + 1, end);
        //治
        merge(array, start, mid, end);
    }

    private void merge(int[] arr, int start, int mid, int end) {
        int[] tmp = new int[end - start + 1];
        //存一下变量
        int i = start;
        int j = mid + 1;
        int k = 0;
        //下面就开始两两进行比较,若前面的数大于后面的数,就构成逆序对
        while (i <= mid && j <= end) {
            //若前面小于后面,直接存进去,并且移动前面数所在的数组的指针即可
            if (arr[i] <= arr[j]) {
                tmp[k++] = arr[i++];
            } else {
                //a[i]>a[j]了,那么这一次,从a[i]开始到a[mid]必定都是大于这个a[j]的,因为此时分治的两边已经是各自有序了
                tmp[k++] = arr[j++];
                ret = (ret + mid - i + 1) % 1000000007;
            }
        }
        //各自还有剩余的没比完,直接赋值即可
        //由于上面的循环条件可知,i和j中必定只有一个可能还有剩余没循环完,所以下面两个循环也只会执行一个。
        while (i <= mid) {
            tmp[k++] = arr[i++];
        }
        while (j <= end) {
            tmp[k++] = arr[j++];
        }
        //覆盖原数组
        for (k = 0; k < tmp.length; k++) {
            arr[start + k] = tmp[k];
        }
    }
}
全部评论

相关推荐

程序员牛肉:主要是因为小厂的资金本来就很吃紧,所以更喜欢有实习经历的同学。来了就能上手。 而大厂因为钱多,实习生一天三四百的就不算事。所以愿意培养你,在面试的时候也就不在乎你有没有实习(除非是同级别大厂的实习。) 按照你的简历来看,同质化太严重了。项目也很烂大街。 要么换项目,要么考研。 你现在选择工作的话,前景不是很好了。
点赞 评论 收藏
分享
完美的潜伏者许愿简历通过:我上表jd,请求封我做后端大将军的事,北京有消息了:竟然不许!!! 他们一定是看我没有实习,这才故意驳回我的请求!
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务