数组算法的总结

数组相关算法的学习。

1、数组循环移位

设计:把含有N个元素的数组循环右移K位,要求时间复杂度0(N),且只允许使用两个附加变量。


假设原数组序列 abcdef1234  ,要求变换成的数组序列为 1234abcdef,即循环右移了4位。相比之后,其中有两段的顺序是不变的:

1234和 abcdef,可把这两段看成两个整体。右移K位的过程就是把数组的两部分交换一下。交换的过程通过以下步骤完成:

1)逆序排序 abcdef:    abcdef1234  -->fedcba1234;
2)逆序排序1234:   fedcba1234 -->fedcba4321;
3)全部逆序1234:   fedcba4321-->1234abcdef;


伪代码:

Reverse(int *arr,int b ,int e)//翻转一小段数组
{
	for(;b < e;b++,e--)
	{
		int temp = arr[e];//使用了一个辅助变量
		arr[e] = arr[b];
		arr[b] = temp;
	}
}

RightShift(int * arr,int N, int K)
{
	K  %= N;//右移的位置
	Reverse(arr,0 ,N -K -1); //翻转前N-K个数
	Reverse(arr,N - K ,N - 1);//翻转后K个数
	Reverse(arr,0,N -1);//翻转前N个数(所有的数)
}

可以在线性时间内实现右移操作。


2、求数组的子数组之和的最大值

(1)一维数组

一个有N个整数的一维数组 (A[0],A[1],.......,A[n-2],A[n-1],),这个数组当然有很多的子数组,那么子数组之和的最大值是什么?

设计思考:

数组的开始和末尾的下标分别为i和j

1)当0 = i = j时,元素A[0]本身构成和最大的一段  

2)当0 =i < j 时,和最大的一段以A[0]开始  

3)当0 < i时,元素A[0]跟和最大的一段没有关系    

由以上三种情况看出,可以将一个大问题(N个元素数组)转化为一个较小的问题(n - 1个元素的数组):

(A[1],..A[n-1])中的最大的一段之和为All[1]

(A[1],..A[n-1])中包含A[1]的和最大是一段为Start[1]。

根据上述分析的三种情况,(A[0],..A[n-1])中的问题的解All[0]是三种情况的最大值max{A[0],  A[0]+start[1], All[1]}.可用动态规划方式解决。

#define  max(x,y)      ((x>y)?x:y)

int MaxSum(int * A,int n)
{
	Start[n - 1] = A[n-1];//最后的Start数组成员(包含i的最大段)和All数组成员(i之后的最大段)
	All[n - 1] = A[n - 1];
	for(i = n - 2 ; i >= 0;i--)//依次往前计算
	{
		Start[i] = max(A[i], A[i] + Start[i + 1]);// Start[i]是包含A[i]的和最大段
		All[i] = max(Start[i],All[i + 1]);//All[i]是i到n-1中的和最大段
	}
	return All[0];//遍历完数组,All[0] 中存放结果
}

复杂度是O(N)

(2)二维数组

一个有N个整数的二维数组,那么子数组之和的最大值是什么?(需要的是每个一维数组中的子数组的前后下标一致,如起始和终结都为 i和j)
其实这个问题是一维的,可以把每一列中第a行和第c行之间的元素看成一个整体。即求数组(BC[1],..,BC[M])中的最大的一段,其中
BC[i] = B[a][i] + ...+ B[c][i].
这样࿰
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值