与最大子段和类似,注意处理负数的情况。
// 子数组的最大乘积
int MaxProduct(int *a, int n)
{
int maxProduct = 1; // max positive product at current position
int minProduct = 1; // min negative product at current position
int r = 1; // result, max multiplication totally
for (int i = 0; i < n; i++)
{
if (a[i] > 0)
{
maxProduct *= a[i];
minProduct = min(minProduct * a[i], 1);
}
else if (a[i] == 0)
{
maxProduct = 1;
minProduct = 1;
}
else // a[i] < 0
{
int temp = maxProduct;
maxProduct = max(minProduct * a[i], 1);
minProduct = temp * a[i];
}
r = max(r, maxProduct);
}
return r;
}
数组循环移位
将一个含有n个元素的数组向右循环移动k位,要求时间复杂度是O(n),且只能使用两个额外的变量,这是在微软的编程之美上看到的一道题。
比如数组 1 2 3 4循环右移1位 将变成 4 1 2 3, 观察可知1 2 3 的顺序在移位前后没有改变,只是和4的位置交换了一下,所以等同于1 2 3 4 先划分为两部分 1 2 3 | 4,然后将1 2 3逆序,再将4 逆序 得到 3 2 1 4,最后整体逆序 得到 4 1 2 3。
// 将buffer中start和end之间的元素逆序
void Reverse( int buffer[], int start, int end )
{
while ( start < end )
{
int temp = buffer[ start ] ;
buffer[ start++ ] = buffer[ end ] ;
buffer[ end-- ] = temp ;
}
}
// 将含有n个元素的数组buffer右移k位
void Shift( int buffer[], int n, int k )
{
k %= n ;
Reverse( buffer, 0, n - k - 1) ;
Reverse( buffer, n - k, n - 1 ) ;
Reverse( buffer, 0, n - 1 ) ;
}
字符串逆序
给定一个含有n个元素的字符数组a,将其原地逆序。
可能您觉得这不是关于数组的,而是关于字符串的。是的。但是别忘了题目要求的是原地逆序,也就是不允许额外分配空间,那么参数肯定是字符数组形式,因为字符串是不能被修改的(这里只C/C++中的字符串常量),所以,和数组有关了吧,只不过不是整型数组,而是字符数组。用两个指针分别指向字符数组的首位,交换其对应的字符,然后两个指针分别向数组中央移动,直到交叉。
// 字符串逆序
void Reverse(char *a, int n)
{
int left = 0;
int right = n - 1;
while (left < right)
{
char temp = a[left] ;
a[left++] = a[right] ;
a[right--] = temp ;
}
}
组合问题
给定一个含有n个元素的整型数组a,从中任取m个元素,求所有组合。比如下面的例子:
a = 1, 2, 3, 4, 5
m = 3
输出:
1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5
2 3 4, 2 3 5, 2 4 5
3 4 5
典型的排列组合问题,首选回溯法,为了简化问题,我们将a中n个元素值分别设置为1-n。







