《九日集训》第五日

本文介绍了C语言中的指针基础知识,包括指针定义、取地址、通过指针取值,以及内存管理的malloc和realloc函数。详细讲解了如何在函数中返回数组,以及位运算判断奇偶数的方法。提供了多个示例题目的解决方案,如数组重组、串联、基于排列构建数组和动态求和。最后,总结了动态和内存分配相关的知识点。
摘要由CSDN通过智能技术生成

一、今日知识点总结

  1. 指针(pointer)定义:用来存放地址的变量。

  2. 定义一个指针变量

    指针类型  *变量名
    int *intp
    char *charp
    float *floatp
    
  3. 取一个变量的地址

    //基本类型的地址
    int a = 3;
    int *p = &a; 
    //数组的地址
    int a[]= int [4];
    int *p = a;
    
    
  4. 给定地址,取地址对应的值

    int a = 3;
    int *p = &a; 
    
    //p代表地址。*p代表地址为p的地方存储的内容
    a = *p;
    
  5. 内存申请**(新知识点)**

    **malloc(参数) **:分配一定大小的内存空间。

    realloc(参数) :重新分配一定大小的内存空间

    使用函数malloc(int c) 来申请大小为c个字节的地址。需要将返回值强制类型转换为需要的地址类型

    int *p  = (int *)malloc(1024); //申请一个1024字节的内存,并将首地址赋值给指针p
    
    //申请一个数组的内存,
    int *p = (int *)malloc(sizeof(int)*n);
    //int 表示该数组是整形数组
    //sizeof()数组存储一个数据需要的内存大小,n表示数组的长度(len)
    
    
    //下面是realloc()函数的使用
    int* getConcatenation(int* nums, int numsSize, int* returnSize) {
        int i;
        *returnSize = numsSize * 2;
        nums = (int *)realloc(nums, sizeof(int) * *returnSize);
    	//nums 是数组。并且该数组已经存在。 *returnSize 表示返回数组长度
        for (i = 0; i < numsSize; i++) {
            nums[i + numsSize] = nums[i];
        }
    
        return nums;
    }
    
  6. 返回数组**(新知识点)**

    问题:当一个函数的返回值为数组时,在C中函数只能有一个返回值。

    解决办法:定义一个全局变量,将其指针传入到函数内,当改变指针指向的值时,就可以改变全局变量的值。

    int *getList(int *nums,int numsSize,int *returnSize){
        //
        *returnSize = 4}
    
    //调用该函数
    int a[] = {1,2,3,4};
    int rSize;
    getList(a,4,&rSize);
    
  7. 范式 就是指针相关的一些写法规范 (也就时对上面知识点的综合应用)

    int *func(int *nums,int numsSize,int *returnSize){
        int *ret = (int *)malloc(sizeof(int) *numsSize);
     
        *returnSize = 1231;
        return ret;
    }
    
  8. 数组类型返回值,返回的时数组的首地址。

二、今日做题记录

第一题

1470.重新排列数组

给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,…,xn,y1,y2,…,yn] 的格式排列。

请你将数组按 [x1,y1,x2,y2,…,xn,yn] 格式重新排列,返回重排后的数组。

解题:

暴力解法:按题意将已知数组中的值,塞入到新数组中。

int* shuffle(int* nums, int numsSize, int n, int* returnSize){
    int *result = (int *)malloc(sizeof(int)*numsSize);
    int i,index;
    index = 0;//用来维护新数组的下标,就不用去通过i来计算下标了。
    for(i = 0;i<n;i++){
        result[index] = nums[i];
        index ++;
        result[index] = nums[n+i];
        index ++;
    }
    *returnSize = numsSize;
    return result;
}

英雄哥的解法:知道新数组的规律,按要求从旧数组中找对应的值。

/**
 * Note: The returned array must be malloced, assume caller calls free().  // (1)
 */
int* shuffle(int* nums, int numsSize, int n, int* returnSize){             // (2)
    int i;
    int *ret = (int *)malloc( sizeof(int) * numsSize );                    // (3)
    for(i = 0; i < numsSize; ++i) {                                        // (4)
        if(i & 1) {
            ret[i] = nums[n + i/2];
        }else {
            ret[i] = nums[(i+1)/2];
        }
    }
    *returnSize = numsSize;                                                // (5)
    return ret;                                                            // (6)
}

知识点:

i & 1 就是i的二进制与1的二进制求与运算,如果结果为1,表示i为奇数数。

第二题

1929.数组串联

给你一个长度为 n 的整数数组 nums 。请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 <= i < n 的 i ,满足下述所有要求:

ans[i] == nums[i]
ans[i + n] == nums[i]
具体而言,ans 由两个 nums 数组 串联 形成。

返回数组 ans 。

解题

int* getConcatenation(int* nums, int numsSize, int* returnSize){
    int *result = (int *)malloc(sizeof(int)*numsSize*2);
    int i;
    for(i=0;i<numsSize;i++){
        result[i] = nums[i];
        result[numsSize+i] = nums[i];
    }
    *returnSize = numsSize*2;
    return result;
}
第三题

1920,基于排列构建数组

给你一个 从 0 开始的排列 nums(下标也从 0 开始)。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i(0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans 。

从 0 开始的排列 nums 是一个由 0 到 nums.length - 1(0 和 nums.length - 1 也包含在内)的不同整数组成的数组。

题解:

int* buildArray(int* nums, int numsSize, int* returnSize){
    int *result = (int *)malloc(numsSize*sizeof(int));
    int i;
    for (i=0;i<numsSize;i++){
        result[i] = nums[nums[i]];
    } 
    *returnSize = numsSize;
    return result;
}
第四题

1480,一维数组的动态和

给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。

请返回 nums 的动态和。

方法1:申请新数组内存。

int* runningSum(int* nums, int numsSize, int* returnSize){
    int *result = (int *)malloc(sizeof(int)* numsSize);
    if(numsSize==0){
        *returnSize = numsSize;
        return nums;
    }
    result[0] = nums[0];
    int i;
    for(i=1;i<numsSize;i++){
        result[i] = result[i-1]+nums[i];
    }
    *returnSize = numsSize;
    return result;
}

原地进行(就在nums数组中进行操作)

int* runningSum(int* nums, int numsSize, int* returnSize){
    if(numsSize==0){  //在该题情况下  该条件可以去掉
        *returnSize = numsSize;
        return nums;
    }
    int i;
    for(i=1;i<numsSize;i++){
        nums[i] += nums[i-1];
    }
    *returnSize = numsSize;
    return nums;
}
第五题

剑指Offer 58-II,左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

char* reverseLeftWords(char* s, int n){
    if(n==0){
        return s;
    }
    int len = strlen(s);
    char *result = (char *)malloc(sizeof(char)*(len +1));
    int i;
    for(i=0;i<len;i++){
        result[i]=s[(i+n)%len];
    }
    result[len] = '\0';
    return result;
}

三、今日收获

1, 两个申请分配内存的函数

**malloc(参数) **:分配一定大小的内存空间。

realloc(参数) :重新分配一定大小的内存空间

2,如何在函数中返回数组。

3,位运算判断整数的奇和偶。

四、今日疑问

暂无

五、其他参考

  1. [九日集训,LeetCode 基础指南–指针](https://blog.csdn.net/WhereIsHeroFrom/article/details/121551694))

是收费的,请加入博主九日集训计划,你将获得免费观看机会。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值