【问题标题】:Function is not able to return elements in returnSize array in the problem函数不能返回returnSize数组中的元素的问题
【发布时间】:2020-01-12 22:53:40
【问题描述】:

我尝试解决在线编码平台 LeetCode 中的一个 C 编码问题二和 我无法返回整数指针大小。

问题: 给定一个整数数组,返回两个数字的索引,使它们加起来为一个特定的目标。您可以假设每个输入都只有一个解决方案,并且您不能两次使用相同的元素。

例子:

给定 nums = [2, 7, 11, 15],目标 = 9,

因为 nums[0] + nums[1] = 2 + 7 = 9, 返回 [0, 1]。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i,j,sum=0,n1=0,n2=0,sz=1;
    int *re;
    re = (int*)malloc(sizeof(returnSize));

    for(i=0;i<numsSize;i++){
        
         if(sum==target){
                break;
         }

         n1 = i;
         for(j=i+1;j<numsSize;j++){
              sum = nums[i]+nums[j];
            
              if(sum==target){
                   n2 = j;
                   re[0] = n1;
                   re[1] = n2;
                   break;
              }
         }  
    }
    
    return re;
}

“我希望nums = [2, 7, 11, 15]target = 9的输出是[0, 1],但实际输出是]

【问题讨论】:

  • 另请注意,您分配的内存内容并不总是被初始化。
  • 你不应该通过覆盖returnSize来返回数组。您应该通过将返回数组的大小写入returnSize 引用的变量来返回。
  • LeetCode 的问题陈述有缺陷。它无法说明returnSize 参数的用途,如果是返回数组的大小,则单位是元素还是字节。而且,由于大小必然是两个元素,所以不清楚为什么会有参数浪费地返回这个常量。

标签: c arrays loops for-loop pointers


【解决方案1】:

我无法重现提供的数组的问题。但是无论如何功能都不正确..

而不是这个语句(malloc调用的参数没有意义)

re = (int*)malloc(sizeof(returnSize));
                         ^^^^^^^^^^^

应该有

re = (int*)malloc(sizeof( sizeof( int ) * *returnSize ));
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^

尽管参数returnSize 是多余的,因为根据您的描述,数组的固定大小等于2。

此外还有一个未使用的变量sz=1

该函数可以调用未定义的行为,因为在target 等于0 的情况下,动态分配的数组未初始化并且具有不确定的值,因为循环退出。

for(i=0;i<numsSize;i++){

     if(sum==target){
            break;
        }
    // ... 

无需动态分配数组。您可以返回一个包含两个元素的结构。

第一个参数应该用限定符const 声明。

函数可以写得更简单,更清晰易读。

#include <stdio.h>

struct PairIndices
{
    size_t first;
    size_t second;
};

struct PairIndices twoSum( const int *a, size_t n, int target )
{
    struct PairIndices pair = { n, n };

    for ( size_t i = 0; i < n && pair.first == n ; i++ )
    {
        size_t j = 1;

        while ( j < n && a[i] + a[j] != target ) j++;

        if ( j != n )
        {
            pair.first  = i;
            pair.second = j;
        }
    }

    return pair;
}

int main(void) 
{
    int a[] = { 2, 7, 11, 15 };
    const size_t N = sizeof( a ) / sizeof( *a );
    int target = 9;

    struct PairIndices pair = twoSum( a, N, target );

    if ( pair.first != N )
    {
        printf( "a[%zu] + a[%zu] == %d\n", pair.first, pair.second, target );
    }
    else
    {
        printf( "There are no two elements in the array "
                "sum of which is equal to %d\n", target );
    }

    return 0;
}

程序输出是

a[0] + a[1] == 9

【讨论】:

    【解决方案2】:

    函数的接口旨在提供两部分的结果,即数组及其大小。
    您不应该通过覆盖 returnSize 来返回数组。
    您应该通过将返回数组的大小写入指针 returnSize 引用的 int 变量来返回数组的大小(并可能检查它是否不是 NULL 指针)。

    数组(即新分配的指针)应该通过return 返回,当然你可以这样做。但是通过覆盖返回参数指针来做到这一点是间接导致问题的原因。 (需要mre 来跟踪观察到的问题。)

    顺便说一句,我发现这一点只是因为看到您忽略并覆盖了其中一个参数,即指针。如果这是正确的,那么函数的接口将是低效的。情况可能是这样,但通常不是为了挑战。

    【讨论】:

    • 问题说明不充分。无论如何,接口都是低效的,因为已知必要的大小是两个元素。并且问题没有说明大小是以元素还是字节为单位给出的。
    【解决方案3】:

    您可以在 for 循环中返回以减少代码的复杂度

    这样会更易读

    #include<stdio.h>
    #include<stdlib.h>
    
    int* twoSum(int* nums, int numsSize, int target){
        int i,j;
        int* returnSize= (int*)malloc(sizeof(int)*2);
        for(i=0;i<numsSize;i++){
            for(j=i+1;j<numsSize;j++){
                if(nums[i]+nums[j]==target){
                    returnSize[0] = i;
                    returnSize[1] = j;
                    return returnSize;
                }
            }  
        }
        free(returnSize);
        return NULL;
    }
    int main(){
        int Test[4]={2, 7, 11, 15};
        int Target=18;
        int *Result=twoSum(Test,4,Target);
        if(Result){//not NULL
            printf("place:[%d,%d]\n",Result[0],Result[1]);
            printf("Value:[%d,%d]\n",Test[Result[0]],Test[Result[1]]);
            free(Result);
        }
        return 0;
    }
    

    【讨论】:

    • 挑战给出了一个不能改变的例程原型
    • 我在现实世界中给出建议,我不知道 LeetCode 怎么样。
    猜你喜欢
    • 2017-03-20
    • 2011-08-07
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    相关资源
    最近更新 更多