# 创新工场两道笔试题0919

### 【题目1】

char* remove_multiple_char(char* str)
{
assert(str != NULL);
char* tmp = str;
char* tmp2 = str;
bool hash_table[256] = {false};
while(*tmp2 != '\0')
{
if (!hash_table[*tmp2 - '\0'])
{
hash_table[*tmp2 - '\0'] = true;
*tmp++ = *tmp2++;
}
else
{
tmp2++;
}
}
*tmp = '\0';
return str;
}

### 【题目2】

//每个序列的逆序对，可以用递归分治
int g_inverse_count = 0;
void merge_core(int a[], int begin, int mid, int end)
{
int i = begin;
int j = mid+1;
int *b = new int[end - begin + 1];
int k = 0;
while(i <= mid && j <= end)
{
if(a[i] < a[j])
b[k++] = a[i++];
else
{
b[k++] = a[j++];
g_inverse_count += (mid - i + 1);
//举个例子，原序列是9 10 2 4 3
//最后要合并的两个左右序列是2 9 10 和4 3
//刚开始a[i]=2 a[j] = 4，a[i]<a[j]不存在逆序对，将i++,a[i]->9
//这时候a[i]>a[j],存在逆序对，并且前一个序列中a[i+1...mid]因为是已经排序的，
//后面的每个数肯定也大于a[i],当然也大于a[j],当然也和a[j]成逆序对，这时候的逆序对的个数应该为mid-i+1
}
}
while(i <= mid)
{
b[k++] = a[i++];
}
while(j <= end)
b[k++] = a[j++];
for (i = 0; i < k; i++)
a[begin + i] = b[i];//替换原来的
delete []b;
}

void merge_sort(int a[], int first, int last)
{
if (first < last)
{
int mid = (last + first)/2;
merge_sort(a, first, mid);
merge_sort(a, mid+1, last);
merge_core(a, first, mid, last);
}
}

### 【测试】

int main()
{
int data[] = {7, 1, 9, 10, 2, 3, 4};
merge_sort(data, 0, 6);
cout<<g_inverse_count;
g_inverse_count = 0;
int data2[] = {9, 10, 2, 4, 3};
merge_sort(data2, 0, 4);
cout<<g_inverse_count;

}