我在采访中遇到了以下问题。
完成此功能以返回反转数组而不修改函数签名或原始数组。请注意,此处不应使用静态数据类型。
假设arrayLength是2的幂,即2 ^ n。 - >我认为这就是诀窍。
int* reverse(int *array, int arrayLength){
}
请帮忙。 请注意,我无法真正想到问题的解决方案。面试官暗示使用2 ^ n进行推理,但我无法真正想到解决方案。
答案 0 :(得分:3)
这个怎么样:
int* reverse(int *array, int arrayLength){
if (arrayLength==1) {
int* out=(int*)malloc(sizeof(int));
out[0] = array[0];
return out;
}
int* left = reverse(array+arrayLength/2, arrayLength-arrayLength/2);
int* right = reverse(array,arrayLength/2);
int* out = (int*)realloc(left, sizeof(int)*arrayLength);
memcpy(out+arrayLength/2, right, sizeof(int)*(arrayLength/2));
free(right);
return out;
}
答案 1 :(得分:2)
int* reverse(int *array, int arrayLength){
if(arrayLength == 0) return array;
int* ret = (int*)malloc(arrayLength*sizeof(int));
for(int i=0;i<arrayLength;i++) ret[i] = array[arrayLength-1-i];
return reverse(ret, 0); // technically recursive
}
答案 2 :(得分:2)
同意OP,提示是&#34; 2 ^ n&#34;。与许多递归函数一样:分而治之。
这个例程首先处理错误的参数和简单的长度。接下来,将长度分成两半并将其反转。通过连接反转的左和右子阵列来形成结果。首先,对,然后离开。
通常的清理
#include <string.h>
#include <stdlib.h>
int* reverse(int *array, int arrayLength) {
// Check parameters
if (array == NULL || arrayLength < 0) {
; // TBD HandleBadParameters();
}
// Allocate space for result, not much to do if length <= 1
int *y = malloc(arrayLength * sizeof *y);
if (y == NULL) {
; // TBD HandleOOM();
}
if (arrayLength <= 1) {
memcpy(y, array, arrayLength * sizeof *y);
return y;
}
// Find reverse of the two halves
int halflength = arrayLength / 2;
int *left = reverse(array, halflength);
int *right = reverse(&array[halflength], halflength);
// Append them to the result - in reverse order
memcpy(y, right, halflength * sizeof *y);
memcpy(&y[halflength], left, halflength * sizeof *y);
// Clean-up and return
free(right);
free(left);
return y;
}
答案 3 :(得分:1)
这是(并且有效):
int *reverse(int *array, int arrayLength)
{
if (arrayLength > 1) {
int i, n = arrayLength >> 1;
int *m = calloc(n, sizeof(int));
memcpy(m, array, n*sizeof(int));
memcpy(array, array + n, n*sizeof(int));
memcpy(array + n, m, n*sizeof(int));
free(m);
reverse(array, n);
reverse(array+n, n);
} /* for */
return array;
} /* reverse */
它可以在没有临时存储的情况下完成,但你必须迭代一点。
int *reverse(int *a, int al)
{
if (al > 1) {
int i, a1 = al >> 1;
for (i = 0; i < a1; i++) {
int temp = a[i];
a[i] = a[i + a1];
a[i + a1] = temp;
} /* for */
reverse(a, a1);
reverse(a+a1, a1);
} /* for */
return a;
} /* reverse */
但是,从边界到中间进行交换并完全迭代会更好。
int *reverse(int *array, int arrayLength)
{
int a, b;
for (a = 0, b = arrayLength-1; a < b; a++, b--) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
} /* for */
return array;
} /* reverse */
对于那些要求非自修改阵列的人来说,这种效率非常低效:
int *reverse(int *array, int arrayLength)
{
int *a1, *a2;
int *res;
if (arrayLength > 1) {
int l = arrayLength >> 1;
a1 = reverse(array, l);
a2 = reverse(array + l, l);
res = calloc(arrayLength, sizeof(int));
memcpy(res, a2, l*sizeof(int));
memcpy(res+l, a1, l*sizeof(int));
free(a1);
free(a2);
} else {
/* we return always memory alloc'd with malloc() so we have to do this. */
res = malloc(sizeof(int));
*res = array[0];
} /* if */
return res;
} /* reverse */
答案 4 :(得分:0)
嗯,这是一种偷偷摸摸的方式,它并不关心阵列的长度。注意:我假设您无法引入新功能,必须在现有功能中完成所有功能
如果长度是正定的,它会分配内存并复制,然后再次使用负长度和副本调用reverse,然后如果函数以负长度调用,则会反转第一个和最后一个,然后递归通过移动到数组中的下一个调用并缩小长度,直到没有任何东西可以反转,然后递归函数展开
int* reverse(int *array, int arrayLength){
int* result;
if(arrayLength > 0)
{
result =(int*) malloc((sizeof(int)*arrayLength));
memcpy(result, array, sizeof(int)*arrayLength);
reverse(result, -arrayLength);
return result;
}
else if(arrayLength < -1)
{
int end = (-arrayLength)-1;
int temp = array[end];
array[end] = array[0];
array[0] = temp;
return reverse(array+1, arrayLength+2);
}
return array;
}
答案 5 :(得分:0)
考虑到arrayLength
始终是2的幂。我们将函数应用于数组的两个部分,然后以相反的方式连接它们。
最后,如果数组只有一个元素,我们只返回具有相同元素的其他数组。
int* reverse(int *array, int arrayLength){
int * newArray = NULL;
if(arrayLength == 1){
newArray = (int *)malloc(sizeof(int));
*newArray = array[0];
} else if(arrayLength == 2){
newArray = (int *)malloc(2 * sizeof(int));
newArray[0] = array[1];
newArray[1] = array[0];
} else {
// apply to first half
int * first = reverse(array, arrayLength / 2);
// apply to second half
int * second = reverse(array + arrayLength / 2, arrayLength / 2);
// allocate space
newArray = (int *) malloc(arrayLength * sizeof(int));
// copy parts in reverse way
memcpy(newArray, second, arrayLength / 2 * sizeof(int));
memcpy(newArray + arrayLength / 2, first, arrayLength / 2 * sizeof(int));
// free allocated space for parts
free(first);
free(second);
}
return newArray;
}
答案 6 :(得分:0)
我会试一试。
知道阵列长度为2 ^ n意味着它可以安全地减半。我们在每一半上递归调用函数,直到长度为2.此时我们交换两个整数。想想{ 2,1,4,3,6,5,8,7 }
。当我们从那里回来时,每一半都会被合并到它来自的地方({ 4,3,2,1,8,7,6,5}
)。冲洗并重复。
#include <stdio.h>
#include <stdlib.h>
int * reverse( int* arr, int length )
{
if ( length == 1 )
{
int *result = malloc( sizeof( arr[0] ) );
result[0] = arr[0];
return result;
}
int * result = 0;
if ( length == 2 )
{
result = malloc( sizeof( arr[0] ) * 2 );
result[0] = arr[1];
result[1] = arr[0];
}
else
{
int half_length = length / 2;
// named correctly
int * right = reverse( arr, half_length );
int * left = reverse( arr + half_length, half_length );
result = malloc( sizeof( arr[0] ) * length );
for ( int i = 0; i < half_length; ++i )
{
result[i] = left[i];
result[ i + half_length ] = right[i];
}
free( right );
free( left );
}
return result;
}
int main( void )
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int length = 8;
int *reversed = reverse( arr, length );
for ( int i = 0; i < length; ++i )
{
printf( "%d %d\n", arr[i], reversed[i] );
}
free( reversed );
return 0;
}
答案 7 :(得分:0)
对于具有2个以上元素的所有整数数组。 基本思路是从两端交换元素,直到剩余的元素数为1。
int * reverse_array(int * array,int arrayLength) {
if(arrayLength <2)
{
return NULL;
}
else
{
int *array1 = NULL;
int *array2 = NULL;
array1 = malloc(arrayLength*sizeof(int));
memcpy(array1,array,arrayLength*sizeof(int));
/*swap the start and end*/
swap(array1,(array1+arrayLength-1));
/* swap the next pair */
array2 = reverse_array(array1+1,arrayLength-2);
memcpy(array1+1,array2,(arrayLength-2)*sizeof(int));
if(array2!= NULL)
{
free(array2);
}
return array1;
}
}