1.最长非降子序列
时间复杂度:O(nlogn)
代码:
public class 最长非降子序列 {
public static void main(String[] args) {
int []arr={1,2,5,4,6,4,5};
int length=lis(arr);
System.out.println(length);
}
public static int lis(int[] arr){
if (arr==null||arr.length==0) {
return 0;
}
int[] temp =new int[arr.length];
temp[0]=arr[0];
int len=1;
for (int i = 1; i < arr.length; i++) {
int index=lower_bound(temp,len,arr[i]);
temp[index]=arr[i];
if (index==len) {
len++;
}
}
return len;
}
//二分查找求下界
public static int lower_bound(int []temp,int len,int compare){
int low=0;
int high=len-1;
while (low<=high) {
int mid=low+(high-low)/2;
if (compare<=temp[mid]) {
high=mid-1;
}else {
low=mid+1;
}
}
return low;
}
}
2.逆序对数
时间复杂度:O(logn)
代码:
public class 逆序对个数 {
static int count=0;
public static void main(String[] args) {
int []arr={1,2,5,4,6,3,5,5,5};
mergesort(arr, 0,arr.length);
System.out.println(count);
}
public static void mergesort(int []arr,int l,int r){
int []c=new int[arr.length];
int i,j,temp,mid;
if (r>l+1) {
mid=l+(r-l)/2;
mergesort(arr, l, mid);
mergesort(arr, mid, r);
temp=l;
//利用归并排序
for (i = l,j=mid; i < mid&&j<r;) {
if (arr[i]>arr[j]) {
c[temp++]=arr[j++];
count+=mid-i;
}else {
c[temp++]=arr[i++];
}
}
if (j<r) {
for (; j < r; ++j) {
c[temp++]=arr[j];
}
}else {
for (; i < mid;++i) {
c[temp++]=arr[i];
}
}
for (int k = l; k < r; ++k) {
arr[k]=c[k];
}
}
}
}