【解题笔记】指针

1.重新排列数组

给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列。请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列,返回重排后的数组。
链接:https://leetcode-cn.com/problems/shuffle-the-array

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* shuffle(int* nums, int numsSize, int n, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));//动态分配一个内存
    for(int i = 0; i < numsSize; i++){//将正确的顺序放到新排好的内存中
        if(i & 1){
            ret[i] = nums[n + i / 2];
        }
        else{
            ret[i] = nums[(i + 1)/ 2];
        }
    }
    *returnSize = numsSize;
    return ret;
}
// 1 2 3 4| 5 6 7 8 nums
// 1 5 2 6  3 7 4 8 ret
//ret[0] = nums[0]         
//ret[1] = nums[4]
//ret[2] = nums[1]         
//ret[3] = nums[5]      
//ret[4] = nums[2] 
//ret[5] = nums[6]      
//ret[6] = nums[3]     
//ret[7] = nums[7] 
//当ret的下标为偶数时,是nums数组的前半部分  ret[i] = nums[i/2]
//当ret的下标为奇数时,是nums数组的后半部分  ret[i] = nums[n + i / 2]
//i & 1 == 0时,i是偶数
//i & 1 == 1时,i是奇数
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* shuffle(int* nums, int numsSize, int n, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        if(i & 1){
            *(ret + i) = *(nums + n + i / 2);
        }
        else{
            *(ret + i) = *(nums + i / 2);
        }
    }
    *returnSize = numsSize;
    return ret;
}
//*(arr + i ) == arr[i]

2.数组串联

给你一个长度为 n 的整数数组 nums 。请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 <= i < n 的 i ,满足下述所有要求:ans[i] == nums[i];ans[i + n] == nums[i]。具体而言,ans 由两个 nums 数组 串联 形成。返回数组 ans 。
链接:https://leetcode-cn.com/problems/concatenation-of-array

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* getConcatenation(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(2 * numsSize * sizeof(int));//动态为新数组分配一个符合大小的内存
    for(int i = 0; i < numsSize; i++){
        ret[i + numsSize] = ret[i] = nums[i];//给新数组赋值
    }
    *returnSize = 2 * numsSize;//返回数组的大小,扩大了一倍
    return ret;
}
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* getConcatenation(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(2 * numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        *(ret + i + numsSize) = *(ret + i) = *(nums + i);
    }
    *returnSize = 2 * numsSize;
    return ret;
}

3.基于排列构建数组

给你一个 从 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 也包含在内)的不同整数组成的数组
链接:https://leetcode-cn.com/problems/build-array-from-permutation

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* buildArray(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        ret[i] = nums[nums[i]];
    }
    *returnSize = numsSize;
    return ret;
}
//数组元素的值的范围是 0 ~ sizeof(arr) - 1;
//所以每一个arr[i] 都是一个不同的值,所以arr[arr[i]]不会有相同的值

4.一维数组的动态和

给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。请返回 nums 的动态和。
链接:https://leetcode-cn.com/problems/running-sum-of-1d-array

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* runningSum(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        ret[i] = nums[i];
        if(i){
            ret[i] += ret[i-1];
        }
    }
    *returnSize = numsSize;
    return ret;
}
//前缀和 = 包括这个位置前面所有数的和
//当前一个数算出来后,后一个数就等于前一个数+原来这个位置的值
//可以先把这个数赋给ret[i]或者直接前一个数+num[i]
//如果是第一个数,那们新的数就是这个数。
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* runningSum(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    for(int i = 1; i < numsSize; i++){
        nums[i] += nums[i-1];
        ret[i] = nums[i];
    }
    ret[0] = nums[0];
    *returnSize = numsSize;
    return ret;
}
//先把原数组进行更改,再将原数组复制到新数组。

5.左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof

char* reverseLeftWords(char* s, int n){
    int len = strlen(s);
    char *ret = (char *)malloc((len + 1) * sizeof(char));
    for(int i = 0; i < len; i++){
        ret[i] = s[(i + n) % len];
    }
    ret[len] = '\0';
    return ret;
}
//strlen() 求字符串长度不包括'\0',字符串末尾以一个'\0'结尾
//abcdef 2
//cdefab 
//a 0 - 4 ret[4] = s[0]
//b 1 - 5 ret[5] = s[1]
//c 2 - 0 ret[0] = s[2]
//d 3 - 1 ret[1] = s[3]
//e 4 - 2 ret[2] = s[4]
//f 5 - 3 ret[3] = s[5]
//一个数%len 他的值的范围是 0 ~ len - 1;
//如果一个数在k之后,那们他的新下标是 i - k
//若果一个数在k之前,那们他的新下标是 i + len - k
//(i+n)%len :
//新数组的前len - k 个 就是原数组的后len - k个,所以新数组的下标就是原数组下标+k;
//新数组的后k个,就是原数组的前k个,(下标 + k) % len 之后可以让超过最大值后重新回到0
char* reverseLeftWords(char* s, int n){
    int len = strlen(s);
    char *ret = (char *)malloc((len + 1) * sizeof(char));
    for(int i = 0; i < len; i++){
        if(i < n){
            ret[i + len - n] = s[i];
        }
        else{
            ret[i - n] = s[i];
        }
    }
    ret[len] = '\0';
    return ret;
}

6.IP 地址无效化

给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。

所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 "."

链接:力扣

char * defangIPaddr(char * address){
    char *ret = (char *)malloc(1000 * sizeof(char));
    int returnSize = 0;
    for(int i = 0; address[i]; i++){
        if(address[i] == '.'){
            ret[returnSize++] = '[';
            ret[returnSize++] = '.';
            ret[returnSize++] = ']';
        }
        else{
            ret[returnSize++] = address[i];
        }
    }
    ret[returnSize] = '\0';
    return ret;
}
//ip地址无效化,将.变成[.]
//新创建一个字符串数组,将原来的字符串进行复制,当碰到.时,新字符串连续添加三个值[.],
//字符串以nul结尾,是0,
//后置加加是先使用后加加,先将值赋给那个位置,下标再自增

7.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

链接:力扣

char* replaceSpace(char* s){
    char *ret = (char *)malloc(30001 * sizeof(char));
    int returnSize = 0;
    for(int i = 0; s[i]; i++){
        if(s[i] == ' '){
            ret[returnSize++] = '%';
            ret[returnSize++] = '2';
            ret[returnSize++] = '0';
        }
        else{
            ret[returnSize++] = s[i];
        }
    }
    ret[returnSize] = '\0';
    return ret;
}

8.有多少小于当前数字的数字

给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。以数组形式返回答案。
链接:https://leetcode-cn.com/problems/how-many-numbers-are-smaller-than-the-current-number

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        ret[i] = 0;
        for(int j = 0; j < numsSize; j++){
            if(nums[i] > nums[j])
                ret[i]++;
        }
    }
    *returnSize = numsSize;
    return ret;
}
//将新数组的每一个设置为0
//若存在一个比这个数小的,则该位置+1
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    memset(ret, 0, numsSize * sizeof(int));
    for(int i = 0; i < numsSize; i++){
        // ret[i] = 0;
        for(int j = 0; j < numsSize; j++){
            if(nums[i] > nums[j])
                ret[i]++;
        }
    }
    *returnSize = numsSize;
    return ret;
}

9.打印1到最大的n位数

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

链接:力扣

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* printNumbers(int n, int* returnSize){
    int size = pow(10, n) - 1;
    int *ret =(int *)malloc(size * sizeof(int));
    for(int i = 1; i <= size; i++){
        ret[i-1] = i;
    }
    *returnSize = size;
    return ret;
}
//最大的n位数字:10 ^ n -1
//pow(a,b) a的b次幂
//把1~10^n -1 放到一个数组中,返回数组的指针

10.按既定顺序创建目标数组

给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:

  • 目标数组 target 最初为空。
  • 按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
  • 重复上一步,直到在 nums 和 index 中都没有要读取的元素。

请你返回目标数组。题目保证数字插入位置总是存在。

链接:力扣

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* createTargetArray(int* nums, int numsSize, int* index, int indexSize, int* returnSize){
    int *ret = (int *)malloc(numsSize * sizeof(int));
    int len = 0;
    int num, ind;
    for(int i = 0; i < numsSize; i++){
        ind = index[i];
        num = nums[i];
        for(int j = len; j > ind; j--){
            ret[j] = ret[j - 1];
        }
        ret[ind] = nums[i];
        len++;
    }
    *returnSize = len;
    return ret;
}
//先创建一个空数组,然后从左到右往里面填数据,ret[index[i]] = nums[i]
//如果要拆入的位置有数据,将该位置及后面的元素往后移动一个位置,直接插入会造成数据的损失
//若要插入的位置为空,则直接将该数据放入那个位置
//先将index[i]储存起来,要将一个数据插入数组后,数组的长度就会增加一
//从最后一个逐渐往前移动,移动到下标为ind时,停止,然后将把这个位置赋给nums[i];然后长度增加

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值