zoukankan      html  css  js  c++  java
  • 数组中的逆序对

    题目

    在数组中的两个数字假设前面一个数字大于后面的数字。则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
    比如:{7,5,6,4},一共存在5个逆序对,各自是(7,6)(7,5)(7,4)(6,4)和(5,4)

    思路

    本来是毫无思路的,一般习惯了暴力破解,剑指offer后面的归并排序的思想。让我想到归并排序是好多年前写过的(忘了......果然出来混总是要还的)。

    归并排序的思想是利用分治法。将一个非常大的问题,缩小成一个非常小的问题,将非常长的数组。终于递归分成两个数进行比較。

    逆序对刚好能够利用这一点。当剩两个数的时候。推断前面的是否大于后面的,假设大于后面的。那么就是一个逆序对,并且后面的一般都是排好序的。所以我们让指针从后面開始往前遍历,仅仅要前半部分的数据大于后半部分的最后一个,那么就会大于全部后半部分的。

    如图:

    (图片来自:http://blog.csdn.net/cjf_iceking/article/details/7920153)

    第一层排好序后,回到第二层。这时候我们推断95 和84的大小。95>84。就说明95大于84之前全部的,所以此时的逆序对数就是84加上之前全部的元素个数。

    然后计算完毕后,反着放入新数组。这样后边就不会再次累积了,这事实上借用了归并排序的思想。

    代码

    public static int InversePair(int[] data,int start,int end,int[] temp)
    	{
    		int count=0;  //累积逆序对的总数
    		if(start < end)
    		{
     
    		   int mid = (end+start)/2;
    		
    		   count +=  InversePair(data, start, mid ,temp);
    		   count +=  InversePair(data,mid+1,end,temp);
    		   count += getInversePair(data,start,mid,end,temp);
    		  
    		}    
    		
    		return count;
    	}
    	
    	
    	
    	private static int getInversePair(int[] data, int start,int mid, int end,int[] temp) 
    	{
    		int i=mid;    //前半部分的末尾
    		int count=0; 
    		int j = end;  //后半部分的末尾
    		int index=0;
    		while(i >=start && j>mid)
    		{
    			if(data[i] > data[j])
    			{
    				temp[index++] = data[i--];
    				count += j-mid;  //j之前的全部元素都是逆序对数
    				
    			}
    			else
    			{
    				temp[index++] = data[j--];
    				 
    			}
    			
    		}
    		
    		while(i>=start)
    		{
    			temp[index++] = data[i--];
    		 
    		}
    		
    		while(j>mid)
    		{
    			temp[index++] = data[j--];
    			 
    		}
    		//将其排好序的放入原数组
    		for(int k=0;k<index;k++)
    		{
    			data[end-k] = temp[k];
    		}
    	 
    	 	 
    		
    		return count;
    	}




  • 相关阅读:
    MySQL Workbench的使用教程 (初级入门版)
    优化MySQL语句的十个建议
    Openfire+Spark+Spark Web安装配置(一)
    agsxmpp官方源代码
    (转载)Oracle中删除外键约束、禁用约束、启用约束
    8.手工备份恢复备用数据库(练习10、11)
    (转载)图文推荐给开发人员非常实用的站点
    13.服务器管理恢复RMAN备份(练习20)
    9.手工备份恢复表空间时间点恢复(练习12.13.14)
    12.服务器管理恢复RMAN配置(练习19)
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7267956.html
Copyright © 2011-2022 走看看