【九度OJ1348】|【剑指offer36】数组中的逆序对

题目描述:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。输入:

每个测试案例包括两行:
第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
第二行包含n个整数,每个数组均为int类型。
输出:对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。 样例输入:
4
7 5 6 4
样例输出:
5
方法一:


扫描整个数组逐个数字比较该数字和前面数字的大小,由于每个数字都要和O(n)个数字做比较,因此这个算法的时间复杂度是O(n2)。

import java.util.Scanner;

/**
 * 数组中的逆序对
 * 2014年3月15日 20:44:15
 * @author aqia358
 * 
 */
public class MainLM {

	public static void count(int[] a){
		long sum = 0;
		for(int i = 1; i < a.length; i++){
			int j = i;
			while(j > 0){
				if(a[j - 1] > a[i])
					sum++;
				j--;
			}
		}
		System.out.println(sum);
	}
	
	public static void main(String[] args) {
//		int[] a = {7,5,6,4};
//		int[] a = {9,8,7,6,5,4,3,2,1,0};
//		MainLM.count(a);
		Scanner cin = new Scanner(System.in);
		while(cin.hasNext()){
			int n = cin.nextInt();
			int[] a = new int[n];
			for(int i = 0; i < n; i++){
				a[i] = cin.nextInt();
			}
			MainLM.count(a);
		}
	}
}



方法二:归并的思路

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
 
/**
 * 数组中的逆序对
 * 2014年3月15日 20:44:15
 * @author aqia358
 * 
 */
public class Main {
 
    public static long num = 0;
    public static int[] result;
     
    public static void merge(int[] a, int begin, int end){
        if(begin != end){
            int center = (begin+end)/2;
            merge(a, begin, center);
            merge(a, center+1, end);
            int i = begin;
            int left = begin;
            int right = center+1;
            while(left <= center && right <= end){
                if(a[left] > a[right]){
                    result[i++] = a[right++];
                    num = num + center - left + 1;//最重要的一步
                }else{
                    result[i++] = a[left++];
                }
            }
            while(left <= center ){
                result[i++] = a[left++];
            }
            while(right <= end){
                result[i++] = a[right++];
            }
            for(int j = begin; j <= end; j++){
                a[j] = result[j];
            }
        }
         
    }
     
    public static void main(String[] args) throws IOException {
//      int[] a = {9,8,7,6,5,4,3,2,1,0};
//      int[] a = {7,5,6,4};
//      Main.merge(a, 0, a.length - 1);
//      System.out.println(Main.num);
//      Main.num = 0;
        StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        while(st.nextToken() != st.TT_EOF){
            int m = (int) st.nval;
            int[] a = new int[m];
                        Main.result = new int[m];
            for(int i = 0; i < m; i++){
                st.nextToken();
                a[i] = (int) st.nval;
            }
            Main.merge(a, 0, a.length - 1);
            System.out.println(Main.num);
            Main.num = 0;
        }
    }
}
 
/**************************************************************
    Problem: 1348
    User: aqia358
    Language: Java
    Result: Accepted
    Time:1270 ms
    Memory:43652 kb
****************************************************************/






转载于:https://my.oschina.net/u/1182234/blog/209052

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值