题目很简单
比如现在有一组数组
{8,9,4,8,2,3,1}
对于每个数组成员都有一个自己的位置,对于位置靠后然而数字本身小于前方的,都称为逆序数,比如
2层循环,遍历数组,靠后并且小于本身,count++
代码要吗?要得点 右上角大叉就出现了
---------------------------------------------我是华丽的分割线--------------------------------------------
在考虑这个问题之前,请先大家了解一下归并排序
比如我现在有个数组{8,9,4,8,2,3,1}
我们可以把数组拆成{8}{9}{4}{8}{2}{3}{1}
先取出第一个数8,此时新数组为{8}
继续到第三个数9 ,发现大于新数组的9,自动插入到后面,{8 9}
继续到第三个数4 发现小于新数组的8,这个时候count出8以及8后方的数字,本例为8 9,所以count+2,并且将4插入新数组的首位 {4 8 9}
继续到第四个数8,发现小于新数组的9,这个时候count出9以及9后方的数字,本例为9,所以count+1,并且将8插入新数组的4与8之间 {4 8 8 9}
继续到第五个数2,发现小于新数组的4,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的4与8之间 {2 4 8 8 9}
继续到第六个数3,发现小于新数组的4,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的2与4之间 {2 3 4 8 8 9}
继续到第七个数1,发现小于新数组的2,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的2与4之间 {1 2 3 4 8 8 9}
思考阶段
但是后来我把total设为一万后, jvm炸了,google了许多地方,说是因为递归的时候没有考虑function的深度,同学们可以尝试修复这个问题,本人目前能想到的就是把递归改成一个循环,事先count出原数组长度,如果有更好办法的同学请流言,博主还是 很水的,希望能和大家共同进步。
比如现在有一组数组
{8,9,4,8,2,3,1}
对于每个数组成员都有一个自己的位置,对于位置靠后然而数字本身小于前方的,都称为逆序数,比如
8/4,8/2,8/3,8/1,9/4,9/3,9/8,9/2,9/1,4/2,4/3,等等等等
题目很简单,在一组数组长度为n的数组中找出所有逆序对
先给出最2的办法2层循环,遍历数组,靠后并且小于本身,count++
代码要吗?要得点 右上角大叉就出现了
---------------------------------------------我是华丽的分割线--------------------------------------------
在考虑这个问题之前,请先大家了解一下归并排序
比如我现在有个数组{8,9,4,8,2,3,1}
我们可以把数组拆成{8}{9}{4}{8}{2}{3}{1}
先取出第一个数8,此时新数组为{8}
继续到第三个数9 ,发现大于新数组的9,自动插入到后面,{8 9}
继续到第三个数4 发现小于新数组的8,这个时候count出8以及8后方的数字,本例为8 9,所以count+2,并且将4插入新数组的首位 {4 8 9}
继续到第四个数8,发现小于新数组的9,这个时候count出9以及9后方的数字,本例为9,所以count+1,并且将8插入新数组的4与8之间 {4 8 8 9}
继续到第五个数2,发现小于新数组的4,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的4与8之间 {2 4 8 8 9}
继续到第六个数3,发现小于新数组的4,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的2与4之间 {2 3 4 8 8 9}
继续到第七个数1,发现小于新数组的2,这个时候count出4以及4后方的数字,本例为4 8 8 9,所以count+4,并且将8插入新数组的2与4之间 {1 2 3 4 8 8 9}
好了,这个时候我们不但可以count出所有逆序数,并且排序都完成了,感觉自己棒棒嗒
package lobs.jibunn.mb.jp.suanfa;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class NiXuShu {
public static void main (String args[]) {
int countReverse = 0;
Random rr = new Random();
int total = 2580;
int orgArray[] = new int[total];
for (int x =0; x < total -1; x++) {
orgArray[x] = rr.nextInt(500);
}
int newArray[] = new int[total];
long startTime = System.currentTimeMillis();
int temp;
for (int i = 0; i < total; i++)
{
for (int j = i + 1; j < total; j++)
{
if (orgArray[i] > orgArray[j]) {
countReverse++;
}
}
}
// for (int i = 0; i < total - 1; i++)
// for (int j = 0; j < total - 1 - i; j++)
// if (orgArray[j] > orgArray[j + 1]) {
// temp = orgArray[j];
// orgArray[j] = orgArray[j + 1];
// orgArray[j + 1] = temp;
// }
long endTime = System.currentTimeMillis();
System.out.println("Reverse count is" + countReverse);
System.out.println("Cost>>>>>>>>>>>>>>>>>>>>>>>>>>>" + (endTime-startTime));
//--------------------------------上面是愚蠢的做法捏哈哈哈哈哈哈------------------------------------------------------------------------------------------//
startTime = System.currentTimeMillis();
//Intialize the first number on the array
newArray[0] = orgArray[0];
countReverse = 0;
//Call the calculate function
callCalReverse(countReverse,orgArray,newArray,1,1);
endTime = System.currentTimeMillis();
System.out.println("Cost>>>>>>>>>>>>>>>>>>>>>>>>>>>" + (endTime-startTime));
}
private static void callCalReverse(int countReverse, int a[], int b[],int position,int newArraySize) {
int begin = 0;//calculate the insert position on b
//In this loop we just do the inserting work.
while (true) {
/*Probably that we just need to insert number to last of the array
*/
if (a[position] >= b[newArraySize-1]) {
insertToSortArray(newArraySize,b,a[position],newArraySize);
break;
}
else if (a[position] < b[begin]) {
/* Exp1
* a {3,1}
* b {2,4}
* We need to insert the 3 to group B which between 2 and 4 ,
* then count how many numbers in group B is bigger than 3
* */
countReverse = countReverse + newArraySize - begin;
insertToSortArray(begin,b,a[position],newArraySize);
break;
}
else {
begin++;
}
}
if (position < a.length-1) {
callCalReverse(countReverse,a,b,++position,position);
} else {
System.out.println("Reverse count is" + countReverse);
}
}
/* Insert the number to the array and resort it
* insert 100 to the fifth position
* org: 100 1,2,3,4,101
* after:* 1,2,3,4,100,101 */
public static void insertToSortArray(int begin,int array[],int number, int newArraySize) {
int temp = 0;
for(int i = begin; i <= newArraySize;i++) {
temp = array[i];
array[i] = number;
number = temp;
}
}
}
思考阶段
本人在初始阶段因为考虑到要反复对于新数组进行插入排序,所以用了linkedlist来操作,但是发现效果非常不好,速度要比最简单的2次遍历都慢,大家可以分析下原因?
然后痛定思痛,决定手写个插入数字到新数组的方法,
速度显著提升但是后来我把total设为一万后, jvm炸了,google了许多地方,说是因为递归的时候没有考虑function的深度,同学们可以尝试修复这个问题,本人目前能想到的就是把递归改成一个循环,事先count出原数组长度,如果有更好办法的同学请流言,博主还是 很水的,希望能和大家共同进步。