数组中的逆序对
题目描述:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)。
知识点:
数组
解题思路:
【个人思路】
这个题的直观想法就是循环判断前面的是否大于后面的数字,要是是逆序对则计数加一。
具体代码:
package array;
import java.util.Scanner;
public class InversePair {
public static int InversePairs(int [] array) {
int len=array.length;
int count=0;
for(int i=0;i<len;i++) {
for(int j=i+1;j<len;j++) {
if(array[i]>array[j])
count++;
}
}
return count%1000000007;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
String[] s=str.split(" ");
int num=0;
int[] a=new int[s.length];
for(int i=0;i<a.length;i++) {
a[i]=Integer.parseInt(s[i]);
System.out.print(a[i]+" ");
}
num=InversePairs(a);
System.out.println(num);
}
}
注意点:
牛客提醒:不通过
您的代码已保存
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为50.00%
这种算法的时间复杂度为O(n^2)。
【个人思路】
思考半天毫无思绪,于是看了剑指offer上面的思路,统计逆序对的过程如下先把数组隔成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序。这实际上就是归并排序的思想。
具体代码:
public class Solution {
public int InversePairs(int [] array) {
System.out.println("000000000000");
if(array==null||array.length==0) return 0;
int[] copy=new int[array.length];
for(int i=0;i<array.length;i++) {
copy[i]=array[i];
}
int count=InversePairsCore(array,copy,0,array.length-1);
return count;
}
private static int InversePairsCore(int[] array, int[] copy, int low, int high) {
// TODO Auto-generated method stub
if(low==high) return 0;
int mid=(low+high)>>1;
int leftCount=InversePairsCore(array,copy,low,mid)%1000000007;
int rightCount=InversePairsCore(array,copy,mid+1,high)%1000000007;
int count=0;
int i=mid;
int j=high;
int locCopy=high;
while(i>=low&&j>mid) {
if(array[i]>array[j]) {
count+=j-mid;
copy[locCopy--]=array[i--];
if(count>=1000000007) {
count%=1000000007;
}else {
copy[locCopy--]=array[j--];
}
}
}
for(;i>=low;i--) {
copy[locCopy--]=array[i];
}
for(;j>mid;j--) {
copy[locCopy--]=array[j];
}
for(int s=low;s<=high;s++) {
array[s]=copy[s];
}
return (leftCount+rightCount+count)%1000000007;
}
}
注意点:
这个题其实就是用了归并排序的思想,只不过是归并排序的变形,是在比较的基础上又计算了个数。注意一开始需要复制一个数组,然后边排序边赋值。这个题的思想没有问题,但是牛客总是提醒时间超时。重要的是理解思想。