1.数组分割
http://blog.csdn.net/yyme411/article/details/12156207
#include <stdio.h>
#include <math.h>
#define SUM_MAX 100
#define MLEN 20
int min(int a,int b)
{
if (a<b)
return a;
else
return b;
}
//F[i][j][k]表示前i个元素中选取j个使其和不超过但最逼近k的和
void fenge(int a[],int len,int sum)
{
int i,j,k;
int F[MLEN+1][MLEN/2+1][SUM_MAX/2+1]={0};
int nLimit;
int Path[MLEN+1][MLEN/2+1][SUM_MAX/2+1]={0};
for (i=1;i<=len;i++)
{
nLimit=min(i,len/2);
for (j=1;j<=nLimit;j++)
{
for (k=1;k<=sum/2;k++)
{
F[i][j][k]=F[i-1][j][k];//不选第i个元素
if (k>=a[i-1])
{
if (F[i][j][k]<F[i-1][j-1][k-a[i-1]]+a[i-1])
{
F[i][j][k]=F[i-1][j-1][k-a[i-1]]+a[i-1];//选第i个元素
Path[i][j][k]=1;
}
}
}
}
}
i=len;j=len/2;k=sum/2;//打印对应的数组,这里从F[2len][len][sum/2],k表示和
while (i>=0&&j>=0&&k>=0)
{
if (1==Path[i][j][k])
{
printf("%d ",a[i-1]);
--j;
k=k-a[i-1]; //k表示和的形式,所以每次k要减去打印过的数
}
--i;
}
printf("\n");
}
int main()
{
int a[]={1,5,7,8,9,6,3,11,20,17};
int len=sizeof(a)/sizeof(a[0]); //数组长度
int sum=0;
int i;
for (i=0;i<sizeof(a)/sizeof(a[0]);i++)
sum+=a[i];
fenge(a,len,sum);
system("pause");
return 0;
}
2.寻找发帖水王,即寻找数组中出现次数大于长度的一半的数。
http://www.cnblogs.com/sooner/archive/2013/04/02/2996589.html
3.字数组的最大乘积。 http://liuyangxdgs.blog.163.com/blog/static/2913776320111094252710/
4.连续子数组最大和 http://www.ahathinking.com/archives/120.html
下面说一下由DP而导出的另一种O(N)的实现方式,该方法直观明了,个人比较喜欢,所以后续问题的求解也是基于这种实现方式来的。
仔细看上面DP方案的代码,End[i] = max{arr[i],End[i-1]+arr[i]},如果End[i-1]<0,那么End[i]=arr[i],什么意思?End[i]表示以i元素为结尾的子数组和,如果某一位置使得它小于0了,那么就自当前的arr[i]从新开始,且End[i]最初是从arr[0]开始累加的,所以这可以启示我们:我们只需从头遍历数组元素,并累加求和,如果和小于0了就自当前元素从新开始,否则就一直累加,取其中的最大值便求得解。
5.数组循环移动位置 http://blog.csdn.net/laizemu/article/details/4046791
假设原数组序列为abcd1234,要求变换成的数组序列为1234abcd,即循环右移了4位。比较之后,不难看出,其中有两段的顺序是不变的:1234和abcd,可把这两段看成两个整体。右移K位的过程就是把数组的两部分交换一下。变换的过程通过以下步骤完成:
1. 逆序排列abcd:abcd1234 → dcba1234;
2. 逆序排列1234:dcba1234 → dcba4321;
3. 全部逆序:dcba4321 → 1234abcd。
6.字符串移位包含问题 http://blog.csdn.net/zzran/article/details/8465211
就是利用空间复杂度换取时间复杂度的方法:对于每次的移动,我们观察每次移除的字符,分别是A,A,B,C,D,如果把每次移除的字符放在原始字符串的后面,就会有如下的结果:AABCDA, AABCDAA, AABCDAAB, AABCDAABC, AABCDAABCD,所有移位之后的最后一个字符串,AABCDAABCD,看看有什么特点,它居然包含我们要找的字符串CDAA,可能有人认为这是一种巧合,那再看一个不成立的例子:ABCD, CDBA, ABCD移位并添加后的字符串是ABCDABCD, 可以看到ABCDABCD中有CDAB,但是没有CDBA,故这个算法还是正确的。但是要浪费一点空间。给出核心代码:
[cpp]
view plain
copy
- int is_contain2(char *p_str, char *s_str) {
- int len_p = strlen(p_str);
- char *temp = (char*)malloc(2 * len_p + 1);
- strcpy(temp, p_str);
- strcpy(temp + len_p, p_str);
- if(strstr(temp, s_str)) {
- return 1;
- } else {
- return 0;
- }
- }
7,队列中取最大值问题
http://blog.sina.com.cn/s/blog_6421561201012vq1.html
8.
快速寻找满足条件的两个数
http://www.cnblogs.com/bingwenst/archive/2012/05/22/2513151.html
首先对数组进行排序,时间复杂度为(N*log2N)。
然后令i = 0,j = n-1,看arr[i] + arr[j] 是否等于Sum,如果是,则结束。如果小于
Sum,则i = i + 1;如果大于大于Sum,则 j = j – 1。这样只需要在排好序的数组上遍
历一次,就可以得到最后的结果,时间复杂度为O(N)。两步加起来总的时间复杂
度O(N*log2N)