在CSDN博客看到一篇文章 是阿里实习生店面题
通过观察题目 我得出了
对于这个题要输出的子串存在一个规律:比如输出我们对所有的字符都以一位编码 则对于abcde 这样一个串 输出a记作00001(1) 输出b记作00010(2) 输出c记作00100(4) 输出d记作01000(8) 输出e则记作10000(16) 输出ab 则记作00011(3) 输出bc 则记作00110(6) 输出cd记作01100(12) 输出de则记作11000(24) 输出abc记作00111(7) 输出bcd记作01110(14) 输出cde记作11100(28) 输出abcd记作01111(15) 输出11110(30) 输出abcde 记作11111(31) 则可以发现规律 前5个记作(2^1-1)*2^i 从第六个开始的四个数记作 (2^2-1)*2^i 之后的3个数记作 (2^3-1)*2^i 之后的两个数 (2^4-1)*2^i 之后的一个数记作(2^5-1)*2^i i从零开始. 整体发现规律则是记字符串长度为n, 则对于长度为1的个数为n 长度为2的长度为n-1 对于长度为3的个数为n-2 依次类推 这样我们就可以总结出一个规律 for (i = n; i > 0; --i) { int len = n; int pos = len - i; int j = 0; for (; j < n; ++j){ nums[j] = array[pos] * array[j];}} 在array[]数组中存储的2^0-2^30 这样再做位运算 从而决定输出那个位置的字符就可以 但是貌似这样对时间复杂度没有什么改善 也是O(n*n*n)的
从而给出了一个时间复杂度为O(n^2)的算法
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 15
int main(void)
{
char* str = "abcde";
int array[MAX] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384};
int len = strlen(str);
int i = len;
int n = i * (i + 1) / 2;
int k = 0;
int j = 0;
int* numbers = (int*)malloc(sizeof(int) * n);
if (numbers == NULL)
{
system("pause");
exit(1);
}
for (; i > 0; --i)
{
int pos = len - i + 1;
for (j = 0; j < i; ++j)
{
numbers[k] = (array[pos] - 1) * array[j];
++k;
}
}
for (j = 0; j < n; ++j)
{
int m = 0;
for (k = 1; k <= array[MAX-1]; k <<= 1)
{
if (numbers[j] & k)
{
printf("%c\t", str[m]);
}
++m;
}
printf("\n");
}
system("pause");
return 0;
}
通过观察题目 我得出了
对于这个题要输出的子串存在一个规律:比如输出我们对所有的字符都以一位编码 则对于abcde 这样一个串 输出a记作00001(1) 输出b记作00010(2) 输出c记作00100(4) 输出d记作01000(8) 输出e则记作10000(16) 输出ab 则记作00011(3) 输出bc 则记作00110(6) 输出cd记作01100(12) 输出de则记作11000(24) 输出abc记作00111(7) 输出bcd记作01110(14) 输出cde记作11100(28) 输出abcd记作01111(15) 输出11110(30) 输出abcde 记作11111(31) 则可以发现规律 前5个记作(2^1-1)*2^i 从第六个开始的四个数记作 (2^2-1)*2^i 之后的3个数记作 (2^3-1)*2^i 之后的两个数 (2^4-1)*2^i 之后的一个数记作(2^5-1)*2^i i从零开始. 整体发现规律则是记字符串长度为n, 则对于长度为1的个数为n 长度为2的长度为n-1 对于长度为3的个数为n-2 依次类推 这样我们就可以总结出一个规律 for (i = n; i > 0; --i) { int len = n; int pos = len - i; int j = 0; for (; j < n; ++j){ nums[j] = array[pos] * array[j];}} 在array[]数组中存储的2^0-2^30 这样再做位运算 从而决定输出那个位置的字符就可以 但是貌似这样对时间复杂度没有什么改善 也是O(n*n*n)的
从而给出了一个时间复杂度为O(n^2)的算法
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 15
int main(void)
{
char* str = "abcde";
int array[MAX] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384};
int len = strlen(str);
int i = len;
int n = i * (i + 1) / 2;
int k = 0;
int j = 0;
int* numbers = (int*)malloc(sizeof(int) * n);
if (numbers == NULL)
{
system("pause");
exit(1);
}
for (; i > 0; --i)
{
int pos = len - i + 1;
for (j = 0; j < i; ++j)
{
numbers[k] = (array[pos] - 1) * array[j];
++k;
}
}
for (j = 0; j < n; ++j)
{
int m = 0;
for (k = 1; k <= array[MAX-1]; k <<= 1)
{
if (numbers[j] & k)
{
printf("%c\t", str[m]);
}
++m;
}
printf("\n");
}
system("pause");
return 0;
}