找逆序的对数&&和为n的两个数字&&和为n的连续正数序列

可以采用分治的思想,分成左右两个部分,统计左边和右边的逆序数之后,再统计左右结合的数目。

类似于归并排序,左右两边统计完后都排好序,方便左右结合数目的统计,代码如下:

#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;
int temp[100];
int findreversenum(int *numbers,int beg,int end){
	if(beg == end){
		return 0;
	}
	int mid,leftnum,rightnum,num = 0;
	mid = (beg+end)>>1;
	if(beg<=mid)
		leftnum = findreversenum(numbers,beg,mid);
	if(mid+1<=end)
		rightnum= findreversenum(numbers,mid+1,end);
	int i =mid,j=end,pos = end;
	while(i>=beg && j>=mid+1){
		if(temp[i] >temp[j]){
			numbers[pos--] = temp[i--];
			num += j-mid;
		}
		else
			numbers[pos--] = temp[j--];
	}
	while(i>=beg)
		numbers[pos--] = temp[i--];
	while(j>=mid+1)
		numbers[pos--] = temp[j--];
	for(int k =beg;k<=end;k++)
		temp[k] = numbers[k];
	return num+leftnum+rightnum;
}

int main(){
	int numbers[] = {7,5,6,4};
	for(int i =0;i<4;i++)
		temp[i] = numbers[i];
	int result = findreversenum(numbers,0,3);
	printf("%d",result);
	system("PAUSE");
	return 0;
}

和为n的两个数字:已知给定某个数组,求数组中和为n的任意两个数字,输出即可。

直观想法是O(n*n)的扫描,但注意到找到一个满足条件的解即可。所以可以将数组排序,一个指针指向头部,一个指向尾部,扫描,如果两个指针的和小于n,则指向头部的向后移动;否则,指向尾部的向前移动。

拓展,和为n的连续正数序列,比如求15的,则结果为1+2+3+4,4+5+6,7+8。可以从上题得到启发,两个指针,一个指向1,一个指向2,如果当前和小于15,则后面的指针向后移动;如果大于,则前面的指针向后移动(相当于减少两个指针之间数字的和)。具体看代码:

#include<iostream>
#include<algorithm>
#include<time.h>
using namespace std;
//和为n的两个数
void findsum(int *numbers,int len,int sum){
	int beg =0,end = len;
	while(beg <end){
		int temp = numbers[beg]+numbers[end];
		if(temp == sum){
			printf("找到的两个数是%d和%d,和为%d\n",numbers[beg],numbers[end],sum);
			return;
		}
		if(temp<sum)
			beg++;
		else
			end--;
	}
	printf("没有找到\n");
}
//连续的和为n
void findcsum(int sum){
	int beg =1,end =2,mid = sum/2;
	int cursum = beg+end;
	while(beg<=mid){
		if(cursum == sum){
			for(int i = beg;i<=end;i++)
				printf("%d",i);
			printf("\n");
		}
		while(cursum >sum){
			cursum -= beg;
			beg++;
			if(cursum == sum){
				for(int i = beg;i<=end;i++)
					printf("%d",i);
				printf("\n");
			}
		}
			end++;
			cursum +=end;
	}
}
int main(){
	int numbers[] = {15,4,2,7,11,1};
	int sum;
	scanf("%d",&sum);
	sort(numbers,numbers+6);
	findsum(numbers,5,sum);
	findcsum(15);
	system("PAUSE");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值