【算法笔记】分而治之

分而治之

求逆序数

void Merge(string a,int low,int mid,int high){
   //参考合并两个链表的时候的做法
	int tmpa[high-low+1];
	int ans=0;
	int i=low,j=mid+1,k=0;//i,j分别是指向两个数列对应的位置的,k是指向最终的数列中位置的坐标
	while(i<=mid&&j<=high){
   
		if(a[i]<=a[j]){
   
			tmpa[k++]=a[i++];
		}
		else{
   
			tmpa[k++]=a[j++];
			ans+=(mid-i+1);
		}
	}
	if(i<=mid){
   
		while(i<=mid)
			tmpa[k++]=a[i++];
		
	}
	if(j<=high){
   
		while(j<=high)
			tmpa[k++]=a[j++];
	}
	for(int i=low;i<=high;i++)
		a[i]=tmpa[i-low];
}

void MergeSort(string a,int low,int high){
   
	int mid;
	if(low<high){
   
		mid=(low+high)/2;
		MergeSort(a, low, mid);//对于前半个排序
		MergeSort(a, mid+1, high);//对于后面半个排序
		Merge(a, low, mid,high);//合并
	}
}

求最大元素和次大元素

  • 如果只有一个元素,那么一个最大,另外一个设为负无穷
  • 如果有两个元素,一个是最大,一个是次大
  • 如果有多于两个元素,那么最大的是左右两边当中最大的那一个,次大的是
void Solve(int a[],int low,int high,int &max1,int &max2){
   
  if(low==high){
   
    max1=a[low];
    max2=-100000;
  }
  else if(low==high-1){
   
    max1=a[low]>a[high]?a[low]:a[high];
    max2=a[low]+a[high]-max1;
  }
  else {
   
    int mid=(low+high)/2;
    int lmax1,lmax2;
    solve(a,low,mid,lmax,lmin);
    int rmax1,rmax2;
    solve(a,mid+1,high,rmax,rmin);
    max1=lmax1>rmax1?lmax1:rmax1;
    if(max1==lmax1){
   
      max2=lmax2>rmax1?lmax2:rmax1;
    }
    else{
   
      max2=rmax2>lmax1?rmax2:lmax1;
    }
  }
}

查找序列中第k小的元素

借助快速排序的思想
借用第一个作为枢轴,对于数列进行划分,如果一次划分之后书作的位置i=k-1,那么在这个时候恰好是第k 个元素。
如果k-1<i,那么第k小的元素在前面,那么对于前面的元素进行划分
如果k-1>i,那么第k小的元素应该在后面,如果不是,那么再对于后

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值